如何使用玩笑模拟 window.navigator.language

新手上路,请多包涵

我试图在我的开玩笑单元测试中模拟浏览器中的 window.navigator.language 属性,这样我就可以测试我页面上的内容是否使用了正确的语言

我在网上发现有人使用这个:

Object.defineProperty(window.navigator, 'language', {value: 'es', configurable: 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')
})

对于这些测试,它不会将语言更改为我设置的新语言,始终使用顶部的语言

原文由 the venom 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 590
2 个回答

window.navigator 并且它的属性 是只读的,这就是为什么 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')
})
...

原文由 Estus Flask 发布,翻译遵循 CC BY-SA 4.0 许可协议

在 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');
  });
});

原文由 Eduardo Acosta 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题