【问题标题】:Cannot mock external node module无法模拟外部节点模块
【发布时间】:2019-12-02 22:05:50
【问题描述】:

我正在尝试模拟一个外部模块(感兴趣的人可以使用 jwt_decode),并且我已经看到了许多关于如何使用 Jest 模拟外部节点模块的示例,这既适用于测试套件中的所有测试,也适用于每个测试。测试依据。

我已经能够模拟依赖项,以便它模拟套件中所有测试的返回值,尽管默认函数是我真正关心的全部。

import jwt_decode from 'jwt-decode';

jest.mock('jwt-decode', () => jest.fn().mockReturnValue({
  exp: 12345,
  somethingElse: 'test_value'
}));

这很好用,除了我想测试一个返回的令牌已经过期的场景,这样我就可以验证当这种情况出现时某些 Redux 操作是否被调度。

import jwt_decode from 'jwt-decode';

const decoded = jwt_decode(localStorage.jwtToken);

// set user info and isAuthenticated
store.dispatch(setCurrentUser(decoded));

// this is the scenario I am looking to test
const currentTime = Date.now() / 1000;
if (decoded.exp < currentTime) {
  store.dispatch(logoutUser());
  store.dispatch(clearCurrentProfile());

  window.location.href = '/login';
}

我想为单独的测试修改返回的模拟,以便我可以确保显示的“if”语句等于 false,并执行代码库的其他部分。 p>

如何才能做到这一点?

到目前为止,我尝试过但失败的一些示例包括:

test('some test that will use a different mock' () => {
  // re-assign value of the imported module using the its given alias
  jwt_decode = jest.fn().mockImplementation(() => {
    return {
      exp: 'something_different 9999999999',
      somethingElse: 'I_changed_too'
    };
  });
});

还有

jwt_decode.default = jest.fn().mockImplementation(() => {
   return {
     exp: 'something_different 9999999999',
     somethingElse: 'I_changed_too'
   };
});

还有 jest.spyOn(),如 this SO question 中所见,以及 A Jar of Clay 对同一问题的回答,它提出以下建议:

import { funcToMock } from './somewhere';
jest.mock('./somewhere');

beforeEach(() => {
  funcToMock.mockImplementation(() => { /* default implementation */ });
});

test('case that needs a different implementation of funcToMock', () => {
  funcToMock.mockImplementation(() => { /* implementation specific to this test */ });
  // ...
});

我还在逐个测试的基础上找到了对 creating a util which changes the global localStorage 的建议,但我宁愿不使用真正的 jsonwebtoken,或者不得不担心存储登录凭据。

我一直认为 jwt_decode 在运行应该返回不同模拟值的测试时没有更新,或者更常见的是我收到一条错误消息,指出“.default 不是函数”。

如果您有建议,我将不胜感激。

【问题讨论】:

  • 添加你要测试的代码
  • 是的,我也有同样的问题。
  • 您找到解决此问题的方法了吗?我面临同样的问题。谢谢

标签: javascript reactjs unit-testing mocking jestjs


【解决方案1】:

假设我了解您的最终目标,这种方法怎么样:

在您的项目目录中,与 node_modules 处于同一级别,创建一个名为“__mocks__”的目录,并在该目录中放置一个名为“jwt-decode.js”的文件——有了这个就不需要显式在您的测试模块中模拟 jwt-decode,因为它总是会被自动模拟。

将以下代码放入您的 __mocks__/jst_decode.js 文件中:

export default token => token;

因此,当您正在测试的代码调用jwt_decode(something) 时,返回值将与传入的内容完全相同。

现在您可以编写单元测试来测试您的模块在令牌中给出的各种有效或无效值的行为;只需在你的模块中模拟令牌值,你的 jwt_decode() 模拟实现就会简单地通过它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 2018-07-22
    相关资源
    最近更新 更多