测试用对象工厂动态值问题:批量生成对象重复值求解
解决BudgetFactory生成多对象时属性复用的问题
你遇到的问题根源在于build_obj是类实例的单一私有对象,每次调用getOne()时都直接把这个对象的引用传给Budget构造函数,导致所有生成的Budget实例共享同一份属性数据,自然会出现所有对象属性值完全一样的情况。
要保留现有的链式自定义方法(比如isOnPeriod()、periodIsClosed()),同时让每个生成的Budget对象拥有独立属性,核心是每次生成对象时,基于当前的build_obj模板创建一个新的对象副本,而不是直接传递原引用。
修改方案
1. 修改getOne()方法
将直接传递build_obj引用改为传递其浅拷贝(当前场景下属性都是基本类型和Date,浅拷贝足够):
public getOne(): Budget { // 使用对象展开语法创建新副本,避免引用共享 return new Budget({...this.build_obj}) }
也可以用Object.assign实现相同效果:
return new Budget(Object.assign({}, this.build_obj))
2. 完整修改后的代码
export class BudgetFactory { private build_obj: IBudgetData = { id: faker.number.int(), title: faker.lorem.sentence(3), description: faker.lorem.paragraph(4), opening_date: faker.date.future(), closing_date: faker.date.future(), } public getOne(): Budget { // 创建build_obj的副本,避免引用共享 return new Budget({...this.build_obj}) } public getMany(quantity?: number): Array<Budget> { let items = [] for (let i = 0; i < quantity; i++) { items.push(this.getOne()) } return items } public isOnPeriod(opening_date?: Date, closing_date?: Date): this { this.build_obj.opening_date = opening_date || faker.date.past() this.build_obj.closing_date = closing_date || faker.date.future() return this } public periodIsClosed(opening_date?: Date, closing_date?: Date): this { this.build_obj.closing_date = closing_date || faker.date.past() this.build_obj.opening_date = opening_date || new Date(this.build_obj.closing_date.getTime() - 7 * 24 * 60 * 60 * 1000) return this } public periodIsNotOpenYet(opening_date?: Date, closing_date?: Date): this { this.build_obj.opening_date = opening_date || faker.date.future() this.build_obj.closing_date = closing_date || new Date(this.build_obj.opening_date.getTime() - 7 * 24 * 60 * 60 * 1000) return this } public isClosed(date?: Date): this { this.build_obj.closing_date = date || faker.date.past() return this } }
效果说明
- 链式方法依然可以正常修改
build_obj模板,例如调用factory.isOnPeriod().getMany(5)时,所有5个对象都会基于修改后的模板生成,但每个对象都是独立的副本,属性不会互相影响。 - 每次
getOne()生成的都是新的对象实例,彻底解决了属性复用的问题。
内容的提问来源于stack exchange,提问作者Bernardo Benini Fantin
相关产品推荐
相关产品推荐

