我正在尝试在jest单元测试中模拟浏览器中的window.navigator.language
属性,以便可以测试页面上的内容使用的是正确的语言
我发现有人在网上使用此功能
Object.defineProperty(window.navigator, 'language', {value: 'es', configurable: true});
我已经将其设置在测试文件的顶部,并且可以在其中运行
但是,当我在单个测试中重新定义(并且人们设置为确保可配置性设置为true)时,它不会重新定义它,而只是使用旧值,有人知道肯定要更改它的方法吗?
beforeEach(() => {
jest.clearAllMocks()
Object.defineProperty(global.navigator, 'language', {value: 'es', configurable: true});
wrapper = shallow(<Component {...props} />)
})
it('should do thing 1', () => {
Object.defineProperty(window.navigator, 'language', {value: 'de', configurable: true});
expect(wrapper.state('currentLanguage')).toEqual('de')
})
it('should do thing 2', () => {
Object.defineProperty(window.navigator, 'language', {value: 'pt', configurable: true});
expect(wrapper.state('currentLanguage')).toEqual('pt')
})
对于这些测试,并没有将语言更改为我设置的新语言,而是始终使用顶部的语言。
答案 0 :(得分:2)
window.navigator
and its properties是只读的,这就是为什么需要Object.defineProperty
来设置window.navigator.language
的原因。应该可以多次更改属性值。
问题在于该组件已在beforeEach
中实例化,window.navigator.language
的更改不会影响它。
手动使用Object.defineProperty
来模拟属性将需要存储原始描述符并也手动对其进行恢复。可以使用jest.spyOn
完成。 jest.clearAllMocks()
对于手动间谍/嘲弄无济于事,对于Jest间谍来说可能不需要。
可能应该是:
let languageGetter;
beforeEach(() => {
languageGetter = jest.spyOn(window.navigator, 'language', 'get')
})
it('should do thing 1', () => {
languageGetter.mockReturnValue('de')
wrapper = shallow(<Component {...props} />)
expect(wrapper.state('currentLanguage')).toEqual('de')
})
...
答案 1 :(得分:2)
在 Estus Flask 的回答中添加一点,您还可以监视您的安装文件:
在 jest 配置文件中激活 setupFiles 功能:
setupFiles: ['./test/mock-data/globals.js']
然后在 globals.js 中监视 userAgent 或任何其他属性:
global.userAgent = jest.spyOn(navigator, 'userAgent', 'get');
最后在你的测试中模拟返回值:
describe('abc', () => {
global.userAgent.mockReturnValue(
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4)\
AppleWebKit/600.1.2 (KHTML, like Gecko)\
Version/13.0.0 Safari/600.1.2'
);
test('123', async () => {
const result = await fnThatCallsOrUseTheUserAgent();
expect(result).toEqual('Something');
});
});
答案 2 :(得分:0)
替代
jest 配置文件
setupFiles: ['./test/mock-data/globals.js']
globals.js
const navigator = { language: 'Chalcatongo Mixtec', ...anyOtherPropertiesYouNeed };
Object.defineProperty(window, 'navigator', {
value: navigator,
writable: true
});
然后你可以在你的个人测试设置中自由地改变