【问题标题】:jest not implemented window.alert()开玩笑没有实现 window.alert()
【发布时间】:2019-07-31 23:27:46
【问题描述】:

我用 jest 为我的 API 编写了一个测试。我在测试文件中添加了一个调用我的 API 的函数,如下所示:

import AuthManager from "../Client/Modules/Auth/AuthManager";

并按如下方式使用:

test("login api resolves true", () => {
  return expect(AuthManager.login("test", "test")).resolves.toMatchObject(
    expect.objectContaining({
      accessToken: expect.any(String),
      email: expect.any(String),
      expiresIn: expect.any(Number),
      refreshToken: expect.any(String),
      userFullName: expect.any(String),
      userId: expect.any(Number)
    })
  );
});

我的测试通过了,但出现如下错误:

错误:未实现:window.alert

我该如何解决这个问题?

【问题讨论】:

    标签: reactjs api unit-testing jestjs


    【解决方案1】:

    Jestdefault test environmentjsdom提供的类似浏览器的环境。

    jsdom 实现了实际浏览器将提供的大部分功能(包括全局 window 对象),但它并没有实现所有功能。

    专门针对这种情况,jsdom 没有实现window.alert,而是在调用它时抛出一个Error,如源代码here 所示。


    只要你知道为什么你的代码会启动alert,并且知道除了Error之外你的测试工作正常,那么你就可以通过为window.alert提供一个空实现来抑制Error

    test("login api resolves true", () => {
      const jsdomAlert = window.alert;  // remember the jsdom alert
      window.alert = () => {};  // provide an empty implementation for window.alert
      return expect(AuthManager.login("test", "test")).resolves.toMatchObject(
        expect.objectContaining({
          accessToken: expect.any(String),
          email: expect.any(String),
          expiresIn: expect.any(Number),
          refreshToken: expect.any(String),
          userFullName: expect.any(String),
          userId: expect.any(Number)
        })
      );  // SUCCESS
      window.alert = jsdomAlert;  // restore the jsdom alert
    });
    

    【讨论】:

    • 好建议,但它对我不起作用,因为我仍然收到未实施的错误
    • @dcp 您必须使用jest.fn 正确模拟它,例如window.alert = jest.fn(() => ({})); ;)
    • @GlennMohammad window.alert doesn't return anything 所以如果你想使用 Jest 模拟函数,那就是 window.alert = jest.fn();
    • @brian-lives-outdoors 对,感谢您的更正。我一定是在做白日梦?
    【解决方案2】:

    我解决这个问题的方法实际上是将测试文件顶部的window.alert方法定义为jest spy。这应该适用于任何窗口方法(在我的情况下,我实际上是在测试window.open)。

    请务必在您的测试中调用mockClear(),因为这是一个全局对象,并且它的调用将在测试中持续存在。

    window.alert = jest.fn();
    
    test("login api resolves true", () => {
      window.alert.mockClear();
      /* ... */
    })
    

    【讨论】:

    • 谢谢!当我测试路由并且代码库使用window.location.reload() 时,这解决了我的问题
    • 谢谢!这也解决了我测试在window 对象上具有scrollTo() 方法的组件的问题。
    • 也适用于 window.open()。谢谢!
    【解决方案3】:

    我遇到了window.confirm 这是我对 angular fw 的解决方案。

    let spyOnWindow: jasmine.Spy;
    
    beforeEach((() => {
        TestBed.configureTestingModule({
          declarations: [...],
          imports: [...],
          providers: [...]
        }).compileComponents().then(() => {
          ...
          spyOnWindow = spyOn(window,'confirm');
          ...
        });
    

    一些测试用例

    it('showModal testing function with delete an event', () => {
    spyOnWindow.and.returnValue(true);
    ...
    }
    
    it('showModal testing function with delete an event', () => {
    spyOnWindow.and.returnValue(false);
    ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-11
      • 2020-05-11
      • 2017-11-28
      • 1970-01-01
      • 1970-01-01
      • 2018-02-15
      • 1970-01-01
      • 2021-03-19
      相关资源
      最近更新 更多