简体   繁体   English

如何使用 JavaScript 在 Jest 中模拟服务?

[英]How to mock a service in Jest with JavaScript?

My code looks like this我的代码看起来像这样

const { MyClient } = require('some-service')

const invokeMe = async (input1, input2) => {
  const client = new MyClient({
    name: 'my-name'
  })

  return await client.invoke({
    input1,
    input2
  }).catch((err) => {
    throw err
  })
}

This is what I have, how do I properly mock this service and spy on what it's called with?这就是我所拥有的,我如何正确模拟此服务并监视它的名称?

const { MyClient } = require('some-service')

describe('test my client', () => {
  it('invoke my client', () => {
    const response = {
      data: []
    }
    expect(invokeMe('abc', '123')).resolves.toEqual(response)
    expect(MyClient).toBeCalledWith({
      input1: 'abc',
      input2: '123'
    })
  })
})

Edit: Why does the below still call the original function?编辑:为什么下面仍然调用原始函数?

it('invoke my client', () => {
  const mockInvoke = jest.fn().mockImplementation(() => Promise.resolve({
    data: []
  }))
  const mockMyClient = () => {
    return { invoke: mockInvoke }
  }
  const mockSomeService = {
    MyClient: mockMyClient
  }
  jest.doMock('some-service', () => mockSomeService
  ...
})

You can use jest.mock(moduleName, factory, options) mock the imported service您可以使用jest.mock(moduleName, factory, options)模拟导入的服务

Eg例如

index.js : index.js

const { MyClient } = require('./some-service');

const invokeMe = async (input1, input2) => {
  const client = new MyClient({
    name: 'my-name',
  });

  return await client
    .invoke({
      input1,
      input2,
    })
    .catch((err) => {
      throw err;
    });
};

module.exports = invokeMe;

some-service.js : some-service.js

class MyClient {
  async invoke(input1, input2) {
    return 'real response';
  }
}

module.exports = { MyClient };

index.test.js : index.test.js

const invokeMe = require('./');
const { MyClient } = require('./some-service');

jest.mock('./some-service', () => {
  const mMyClient = { invoke: jest.fn() };
  return { MyClient: jest.fn(() => mMyClient) };
});

describe('60008679', () => {
  it('should invoke', async () => {
    const client = new MyClient();
    client.invoke.mockResolvedValueOnce('fake response');
    const actual = await invokeMe('a', 'b');
    expect(actual).toBe('fake response');
    expect(MyClient).toBeCalledWith({ name: 'my-name' });
    expect(client.invoke).toBeCalledWith({ input1: 'a', input2: 'b' });
  });

  it('should handle error', async () => {
    const client = new MyClient();
    const mError = new Error('some error');
    client.invoke.mockRejectedValueOnce(mError);
    await expect(invokeMe('a', 'b')).rejects.toThrowError(mError);
    expect(MyClient).toBeCalledWith({ name: 'my-name' });
    expect(client.invoke).toBeCalledWith({ input1: 'a', input2: 'b' });
  });
});

Unit test results with 100% coverage: 100% 覆盖率的单元测试结果:

 PASS  src/stackoverflow/60008679/index.test.js (11.029s)
  60008679
    ✓ should invoke (8ms)
    ✓ should handle error (4ms)

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

Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/60008679源代码: https : //github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/60008679

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

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