我试图在Jasmine测试中模拟从typescript文件导出的函数。我希望以下内容模拟导入的foo
并在规范栏中返回值1。
模拟似乎是不必要的,所以我明显遗漏了一些东西。我该如何修复这个例子?
demo.ts:
export function foo(input: any): any {
return 2;
}
export function bar(input: any): any {
return foo(input) + 2;
}
demo.ts.spec:
import * as demo from './demo';
describe('foo:', () => {
it('returns 2', () => {
const actual = demo.foo(1);
expect(actual).toEqual(2);
});
});
describe('bar:', () => {
// let fooSpy;
beforeEach(() => {
spyOn(demo, 'foo' as any).and.returnValue(1); // 'as any' prevents compiler warning
});
it('verifies that foo was called', () => {
const actual = demo.bar(1);
expect(actual).toEqual(3); // mocked 1 + actual 2
expect(demo.foo).toHaveBeenCalled();
});
});
故障:
答案 0 :(得分:3)
来自this issue on Github:你期望在实际实现中使用spied on函数吗?
您的bar
实现会调用foo
的实际实现,因为它直接引用它。在另一个模块中导入时,会创建一个带有新引用的新对象:
// This creates a new object { foo: ..., bar: ... }
import * as demo from './demo';
这些引用仅存在于导入模块中。当您致电spyOn(demo, 'foo')
时,它正在使用该引用。你可能想在你的规范中尝试这个,测试通过的可能性很小:
demo.foo();
expect(demo.foo).toHaveBeenCalled();
期望真正实现bar
来调用模拟的foo
实际上是不可能的。相反,请尝试将bar
视为具有自己的foo
实现。
答案 1 :(得分:1)
杰弗瑞的回答帮助我走上正轨。
要附加间谍附加到firebase.database().ref(this.getUserPath('/savedQuoteList')).once("value")
.then(function(snapshot) {
console.log(snapshot.numChildren());
if(snapshot.numChildren()<3){
this.angularFireDatabase.list(this.getUserPath('/savedQuoteList')).push(q);
console.log("Quote saved.");
}else {
console.log("Too many quotes in list.");
}
});
的右侧参考,产品代码需要进行少量更改。 foo
应该被称为foo()
以下模式适用于测试(并且比我之前使用的复杂工作更清晰。)
demo.ts:
this.foo()
demo.ts.spec:
export function foo(input: any): any {
return 2;
}
export function bar(input: any): any {
return this.foo(input) + 2;
}