繁体   English   中英

Mocking function object 开玩笑

[英]Mocking function object with jest

我目前有一个 object 用于与我的 API api.js

export var Auth = (function () {
    var Login = async function(username, password) {
        //Async login code for interacting with the API
    };
    return {
        Login: Login
    }
});

这个 object 被导入到另一个文件login.js中:

import * as API from './api';

export var LoginRequestHandler = function() {
   //processess user input, then calls:
   try {
       await API.Auth().Login(username, password);
   } catch(e) {
       throw new Error(e);
}

这是我的笑话测试:

import * as API from '../api';
import * as User from '../user';

jest.mock('../api');

const spy = jest.spyOn(API.Auth(), 'Login');
    User.LoginRequestHandler().then(() => {
        expect(spy).toHaveBeenLastCalledWith('theUsername', 'thePassword');
    }).catch(error => console.log(error));

这是我的模拟文件__mock__/api.js

export var Auth = (function () {
    var Login = async function(username, password) {
        return Promise.resolve(true);
    };
    return {
        Login: Login
    }
});

我通过theUsername中的LoginRequestHandler document.getElementId()检索用户名和thePassword ,并为上面的测试创建自己的 DOM。

LoginRequestHandler中添加console.log(username)表明它正在被调用并且能够获取正确的值。 此外,在API.Auth().Login中添加一个console.log(username)也表明它也获得了正确的值。 但是,当我查看测试日志时,我看到:模拟 function Number of calls: 0并且测试结果出现错误。

我假设我试图监视错误的 function,无论如何我可以解决这个问题吗?

每次调用API.Auth()时,它都会返回一个新的 object ,它有一个Login方法。 因此,在LoginRequestHandler function 中创建并由jest.spyOn(API.Auth(), 'Login')语句在您的测试用例中创建的 object 是不同的。 间谍只添加到后一个。 LoginRequestHandler function 中的Login方法未被窥探。

所以,在这里我将使用jest.mock()来模拟api.js模块,而不将模拟的 object 放到__mocks__目录中。 例如

api.js

export var Auth = function () {
  var Login = async function (username, password) {};

  return {
    Login: Login,
  };
};

user.js

import * as API from './api';

export var LoginRequestHandler = async function () {
  const username = 'theUsername';
  const password = 'thePassword';
  try {
    await API.Auth().Login(username, password);
  } catch (e) {
    throw new Error(e);
  }
};

user.test.js

import * as API from './api';
import * as User from './user';

jest.mock('./api', () => {
  const auth = { Login: jest.fn() };
  return {
    Auth: jest.fn(() => auth),
  };
});

describe('61643983', () => {
  afterEach(() => {
    jest.clearAllMocks();
  });
  it('should login', () => {
    expect.assertions(2);

    return User.LoginRequestHandler().then(() => {
      expect(API.Auth).toBeCalledTimes(1);
      expect(API.Auth().Login).toHaveBeenLastCalledWith('theUsername', 'thePassword');
    });
  });

  it('should throw error', () => {
    expect.assertions(4);
    const mError = new Error('user not found');
    API.Auth().Login.mockRejectedValueOnce(mError);

    return User.LoginRequestHandler().catch((e) => {
      expect(API.Auth).toBeCalled();
      expect(API.Auth().Login).toHaveBeenLastCalledWith('theUsername', 'thePassword');
      expect(e).toBeInstanceOf(Error);
      expect(e.message).toMatch(/user not found/);
    });
  });
});

覆盖率 100% 的单元测试结果:

 PASS  stackoverflow/61643983/user.test.js (11.507s)
  61643983
    ✓ should login (5ms)
    ✓ should throw error (3ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 user.js  |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        13.023s

源代码: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/61643983

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM