我有以下角度服务及其茉莉花测试。测试调用f1()和间谍f2()。函数f2采用变量v2并对其进行修改(将字段a设置为3)。应该使用v2调用函数f2(如f1中所声明的那样),但是我的测试在 toHaveBeenCalledWith 上失败,并且表示在f2函数调用之后实际调用了对象。在函数调用之后,jasmine是否与.toHaveBeenCalledWith的参数匹配,这不应该是推荐的方法,或者我在这里犯了一些错误。
服务
export class JasmineTestClass{
constructor(){
}
f2(v2){
v2.a = 3
};
f1(v1){
let v2 = {
a:30
};
this.f2(v2);
}
}
测试
describe('Test', () => {
let service: JasmineTestClass;
beforeEach(() => {
service = new JasmineTestClass();
spyOn(service, 'f2').and.callThrough();
});
let v1 = {
a:2, b:3
};
let v2 = {
a:30
};
it('should succeed', () => {
service.f1(v1);
expect(service.f2).toHaveBeenCalledWith(v2); //this is failing
});
})
日志:
Test should succeed FAILED
Expected spy f2 to have been called with [Object ({a:30})] but actual calls were [Object ({a:3})]
请注意我在测试时在Chrome中进行了调试,并且使用v2 = {a:30}调用函数f2()。
答案 0 :(得分:0)
toHaveBeenCalledWith
在断言时匹配调用参数。
Jasmine间谍只是在内部保存参数引用。可以通过记录service.f2.calls.all()
对象来跟踪调用参数。
这里的问题是f2
修改了通过引用传递的对象。在v2
来电之后的任何地方都不存在v2.a === 30
f2
原始版本。
此类案例的正确策略是创建细粒度测试,每个单元一次测试(方法)。 callThrough
使用的事实表明单位彼此之间没有隔离,默认情况下只使用spyOn(service, 'f2')
存根是个好主意:
it('should succeed', () => {
service.f1(v1);
expect(service.f2).toHaveBeenCalledWith({ a:30 });
});
it('should succeed', () => {
const obj = { a:30 };
service.f2(obj);
expect(obj).toEqual({ a:3 });
});
现在我们正在测试这两种方法到底发生了什么。