如何在茉莉花测试中模拟导出的打字稿函数?
How do I mock an exported typescript function in a jasmine test?
我正在尝试在 Jasmine 测试中模拟从打字稿文件导出的函数。我希望以下内容模拟导入的 foo
和 return bar 规范中的值 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();
});
});
失败:
- 预期 4 等于 3。
- 预期间谍 foo 已被调用。
From this issue on Github: How are you expecting to use the spied on function in your actual implementation?
您的 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
.
实现
Jeffery 的回答帮助我走上了正确的道路。
要附加间谍已附加到正确的参考文献中 foo
产品代码需要稍作更改。 foo()
应该被称为 this.foo()
下面的模式适用于测试(并且比我之前使用的复杂工作要干净得多)。
demo.ts:
export function foo(input: any): any {
return 2;
}
export function bar(input: any): any {
return this.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);
});
it('verifies that foo was called', () => {
const actual = demo.bar(1);
expect(actual).toEqual(3);
expect(demo.foo).toHaveBeenCalled();
});
});
我正在尝试在 Jasmine 测试中模拟从打字稿文件导出的函数。我希望以下内容模拟导入的 foo
和 return bar 规范中的值 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();
});
});
失败:
- 预期 4 等于 3。
- 预期间谍 foo 已被调用。
From this issue on Github: How are you expecting to use the spied on function in your actual implementation?
您的 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
.
Jeffery 的回答帮助我走上了正确的道路。
要附加间谍已附加到正确的参考文献中 foo
产品代码需要稍作更改。 foo()
应该被称为 this.foo()
下面的模式适用于测试(并且比我之前使用的复杂工作要干净得多)。
demo.ts:
export function foo(input: any): any {
return 2;
}
export function bar(input: any): any {
return this.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);
});
it('verifies that foo was called', () => {
const actual = demo.bar(1);
expect(actual).toEqual(3);
expect(demo.foo).toHaveBeenCalled();
});
});