英文:
unexpected behaviors on classes when testing with jest
问题
我在我的项目上进行一些测试,遇到了一些奇怪的行为。
我的代码看起来像这样:
export class Variable {
b;
constructor() {
this.b = 'B';
}
changeValue = () => {
this.b = 'changed B';
};
}
export class DerivedVariable {
v;
constructor(v: Variable[]) {
this.v = v;
}
}
export class Store {
a;
v;
initialize = () => {
this.a = new Variable();
};
get computedValue() {
return [this.a];
}
get computedInstances() {
return new DerivedVariable(this.computedValue);
}
}
我的测试代码:
test('test', () => {
const { a, computedValue, computedInstances, initialize } = new Store();
initialize();
expect(computedValue[0].b).toBe('B');
computedValue[0].changeValue();
expect(a.b).toBe('changed B');
expect(computedInstances.v[0].b).toBe('changed B');
});
我想运行initialize
函数会填充类变量,从而使测试通过。
然而,测试的结果却返回了类似于:
TypeError: Cannot read properties of undefined (reading 'b')
24 | initialize();
25 |
> 26 | expect(computedValue[0].b).toBe('B');
Jest在创建类实例时是否具有异步行为呢?
提前感谢。
- 顺便说一下,当调用一个会改变类变量的函数后,我遇到了类似的问题,我认为这两个问题可能有关。
英文:
I'm working on some tests on my project, and have run in to some weird behaviors.
My code looks something like this:
export class Variable {
b;
constructor() {
this.b = 'B';
}
changeValue = () => {
this.b = 'changed B';
};
}
export class DerivedVariable {
v;
constructor(v: Variable[]) {
this.v = v;
}
}
export class Store {
a;
v;
initialize = () => {
this.a = new Variable();
};
get computedValue() {
return [this.a];
}
get computedInstances() {
return new DerivedVariable(this.computedValue);
}
}
and my test code:
test('test', () => {
const { a, computedValue, computedInstances, initialize } = new Store();
initialize();
expect(computedValue[0].b).toBe('B');
computedValue[0].changeValue();
expect(a.b).toBe('changed B');
expect(computedInstances.v[0].b).toBe('changed B');
});
I figured running the initialize
function would populate the class variable, which would allow the test to pass.
However, the results of the test returns something like:
TypeError: Cannot read properties of undefined (reading 'b')
24 | initialize();
25 |
> 26 | expect(computedValue[0].b).toBe('B');
Does jest have an asynchronous behavior when it comes to creating class instances?
Thanks in advance.
- On a side note, I've run into a similar issue when testing with class variables after calling a function that mutates it, I assume the two issues are related.
答案1
得分: 0
我很难相信我错过了如此明显的东西,
但我通过一些排除法和研究找出了问题所在。
我遇到了一个stackoverflow问题,它引导我朝着正确的方向前进。
显然,关于箭头函数、词法作用域等方面都没有问题,
我只是忘记了JavaScript中对象赋值的工作原理。
重新分配变量a
将填充变量的内存地址到另一个值,
而测试代码中的解构a
将指向“旧”的对象。
在代码中:
test('test', () => {
const { a, computedValue, computedInstances, initialize } = new Store();
// 变量a指向初始值,这将是undefined
initialize();
// 此时,a被分配了一个新创建的变量,这将使解构的"a"在这一点上过时
});
英文:
wow, I can't believe I missed something so obvious,
but I was able to figure out what was wrong with some process of elimination and research.
I ran into a stackoverflow question which led me to the right direction.
Apparently there were no problems at all regarding arrow functions, lexical scopes and whatnot,
I had just forgotten about how object assignment in javascript works.
Reassigning the variable a
would populate the variable with a memory address to another value,
and the destructured a
in the test code would point to the "old" object
In code:
test('test', () => {
const { a, computedValue, computedInstances, initialize } = new Store();
// the variable a points to the initial value, which would be undefined
initialize();
// at this point, a is assigned a newly created Variable, which would make the destructured "a" obsolete at this point
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论