开玩笑期待一个内部有函数的对象

Jest expect an object with functions inside

我正在编写一个 Jest 测试,我在其中调用一个函数并期望 return 中的对象如下:

const repository = container => {

  const makeBooking = (user, booking) => {
    'make booking function called'
  }

  const generateTicket = (paid, booking) => {
    console.log('generate ticket function called')
  }

  const getOrderById = orderId => {
    console.log('get order by ID called')
  }

  const disconnect = () => {
    console.log('disconnect method called')
  }

  return {
    makeBooking,
    getOrderById,
    generateTicket,
    disconnect
  }
}

为了示例,所有这些功能现在都是示例。我现在导出函数,然后在测试中使用它,如下所示:

container = {}

describe('Repository', () => {
  it('should connect with a container', () => {
    let hello = repository(container)

    expect(hello).toMatchObject({
      makeBooking: jest.fn('makeBooking'),
      getOrderById: jest.fn('getOrderById'),
      generateTicket: jest.fn('generateTicket'),
      disconnect: jest.fn('disconnect')
    })
  })
})


我得到的错误是:

 Expected value to match object:
      {"disconnect": [Function mockConstructor], "generateTicket": [Function mockConstructor], "getOrderById": [Function mockConstructor], "makeBooking": [Function mockConstructor]}
    Received:
      {"disconnect": [Function disconnect], "generateTicket": [Function generateTicket], "getOrderById": [Function getOrderById], "makeBooking": [Function makeBooking]}

我需要从存储库对象中模拟 returned 的对象。但是,该对象由代码中所示的命名函数组成。 无论如何,有没有模拟对象内部有功能的对象?

您可以使用 jest.spyOnrepository 的方法创建存根。

您模拟或存根了存储库的方法,您需要使用它们。这就是 service.js 的由来,当然,您可以在任何地方使用该存储库。所以,实际上要测试的方法是service.makeBooking。然后,你可以对版本库的makeBooking方法进行断言,比如检查版本库的mocked/stubbedmakeBooking方法是否被调用。

这里我们使用依赖注入模式将模拟的 hello 对象注入到 service.makeBooking(hello) 方法。

例如

repository.js:

const repository = (container) => {
  const makeBooking = (user, booking) => {
    'make booking function called';
  };

  const generateTicket = (paid, booking) => {
    console.log('generate ticket function called');
  };

  const getOrderById = (orderId) => {
    console.log('get order by ID called');
  };

  const disconnect = () => {
    console.log('disconnect method called');
  };

  return {
    makeBooking,
    getOrderById,
    generateTicket,
    disconnect,
  };
};

module.exports = repository;

repository.test.js:

const repository = require('./repository');

const container = {};

describe('Repository', () => {
  it('should connect with a container', () => {
    let hello = repository(container);

    expect(hello).toMatchObject({
      makeBooking: expect.any(Function),
      getOrderById: expect.any(Function),
      generateTicket: expect.any(Function),
      disconnect: expect.any(Function),
    });
  });

  it('should generate ticket', () => {
    let hello = repository(container);
    const logSpy = jest.spyOn(console, 'log');
    hello.generateTicket();
    expect(logSpy).toBeCalledWith('generate ticket function called');
  });

  // rest test cases same as above
});

带有覆盖率报告的单元测试结果:

 PASS  Whosebug/61268658/repository.test.js (11.281s)
  Repository
    ✓ should connect with a container (5ms)
    ✓ should generate ticket (19ms)

  console.log node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866
    generate ticket function called

---------------|---------|----------|---------|---------|-------------------
File           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------|---------|----------|---------|---------|-------------------
All files      |      80 |      100 |      40 |      80 |                   
 repository.js |      80 |      100 |      40 |      80 | 11,15             
---------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        13.132s

service.js:

const service = {
  makeBooking(hello) {
    return hello.makeBooking();
  },
};

module.exports = service;

service.test.js:

const service = require('./service');
const repository = require('./repository');
const container = {};

describe('service', () => {
  it('should init', () => {
    let hello = repository(container);
    jest.spyOn(hello, 'makeBooking').mockReturnValueOnce('fake data');
    const actual = service.makeBooking(hello);
    expect(actual).toEqual('fake data');
    expect(hello.makeBooking).toBeCalledTimes(1);
  });
});

带有覆盖率报告的单元测试结果:

 PASS  Whosebug/61268658/service.test.js (10.94s)
  service
    ✓ should init (4ms)

---------------|---------|----------|---------|---------|-------------------
File           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------|---------|----------|---------|---------|-------------------
All files      |   76.92 |      100 |   33.33 |   76.92 |                   
 repository.js |      70 |      100 |      20 |      70 | 7,11,15           
 service.js    |     100 |      100 |     100 |     100 |                   
---------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        12.278s

这就是我要找的:

expect.objectContaining({ 
   theProperty: expect.any(Function) 
})