在Sinon中,我可以进行以下操作:
var myObj = {
prop: 'foo'
};
sinon.stub(myObj, 'prop').get(function getterFn() {
return 'bar';
});
myObj.prop; // 'bar'
但是我该如何使用Jest做到同样的效果呢?我不能简单地用jest.fn()
来覆盖该函数,因为它无法替换getter。
"无法设置get的值"
在Sinon中,我可以进行以下操作:
var myObj = {
prop: 'foo'
};
sinon.stub(myObj, 'prop').get(function getterFn() {
return 'bar';
});
myObj.prop; // 'bar'
但是我该如何使用Jest做到同样的效果呢?我不能简单地用jest.fn()
来覆盖该函数,因为它无法替换getter。
"无法设置get的值"
对于其他人来说,Jest 22.1.0版本引入了一项功能,可以监视getter和setter方法。
编辑:就像下面scieslak的答案中所述,因为你可以监视getter和setter方法,所以可以像任何其他函数一样使用Jest模拟它们:
class MyClass {
get something() {
return 'foo'
}
}
jest.spyOn(MyClass.prototype, 'something', 'get').mockReturnValue('bar')
const something = new MyClass().something
expect(something).toEqual('bar')
您可以使用Object.defineProperty
。
Object.defineProperty(myObj, 'prop', {
get: jest.fn(() => 'bar'),
set: jest.fn()
});
configurable: true
添加到你的 defineProperty
函数中。这样应该就可以解决问题了。 - cgat如果你只关心间谍工作,那就使用 @Franey 的答案。但是,如果您实际上需要为 getter 存根一个值,这就是您可以执行的操作:
class Awesomeness {
get isAwesome() {
return true
}
}
describe('Awesomeness', () => {
it('is not always awesome', () => {
const awesomeness = new Awesomeness
jest.spyOn(awesomeness, 'isAwesome', 'get').mockReturnValue(false)
expect(awesomeness.isAwesome).toEqual(false)
})
})
spyOn
,而你在实例上调用了它。 - Ran Lottem//declaration of MyExternalConfigService with getter
@Injectable()
export class MyExternalConfigService {
constructor(private readonly configService: ConfigService) {}
get myProp():string {
return this.configService.get<string>('context.myProp')
}
}
//beforeEach unit test configuration
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
MyServiceToBeTested,
{
provide: MyExternalConfigService,
useValue: new MyExternalConfigService(new ConfigService())
}
]
}).compile()
service = module.get<MyServiceToBeTested>(
MyServiceToBeTested
)
configService = module.get<MyExternalConfigService>MyExternalConfigService)
})
//mocking a value to your test case
it('my test case', ()=>{
jest
.spyOn(configService, 'myProp', 'get')
.mockImplementationOnce(() => 'mockedValue')
...
)
自 Jest v29.5 版本起,您可以像这样使用 jest.replaceProperty:
var myObj = {
prop: 'foo'
};
jest.replaceProperty(myObj, 'prop', 'bar')
myObj.prop; // 'bar'
我通常使用@Franey的{{link1:spyOn答案}},但如果您要模拟整个模块,则可以将其设置为普通参数:
class MyClass {
get something() {
return 'foo'
}
}
// With this here, you are ignoring the whole class, so the property will be set by whatever you set
jest.mock('./MyClass');
test('something', () => {
MyClass.prototype.something = 'bar'
const something = new MyClass().something
expect(something).toEqual('bar')
})
这对于某些特定情况非常有用,但我认为值得一提。
jest@24.9.0
和["module:metro-react-native-babel-preset"]时出现了"something property does not exist"错误,而使用scieslak的解决方案,可以在awesomeness
实例上准确设置spy。在rspec中,我会使用一个叫做any_instance
的方法,并且会mock/stub该类的any_instance
。在jest官方的spyOn
文档中,语法与你的示例有明显的差别。在那个示例中,jest对一个对象字面量进行了spy。 - Fabrizio Bertoglioconst video = { get play() { return true; },};
- Fabrizio Bertoglioprototype
才能使其正常工作。 - Eduardo Russo