Jest模拟方法根据输入返回特定结果

时间:2017-10-24 13:26:44

标签: javascript jestjs

TL;博士

当输入为fs.readdirSync()时,我试图模仿X

所以最初我嘲笑了方法并添加了所需的输出

fs.readdirSync = jest.fn();
fs.readdirSync.mockReturnValue(['my data here']);

虽然现在它总是使用那个输出,但我只想要它一次,而其他它应该是原始方法, 所以AFAIU可以模拟该方法,并且仍然通过执行

使原始方法具有默认值
const originalReaddirSync = fs.readdirSync;
fs.readdirSync = jest.fn(path => originalReaddirSync(path));
fs.readdirSync.mockReturnValueOnce(['my data here']);

这几乎可以完成预期的工作,但是我要覆盖的电话是第二次电话。

问:如果path X返回Y,是否可以说?

我来自PHP背景,我试图用嘲弄来实现以下示例

$mockedObject->shouldReceive('method')
    ->once()
    ->with('this argument')
    ->andReturn(['my data here']);

1 个答案:

答案 0 :(得分:2)

您可以为每个测试用例模拟一次该值:

index.ts

import fs from 'fs';

function readdirSync(path) {
  return fs.readdirSync(path);
}

export { readdirSync };

index.spec.ts

import { readdirSync } from './';
import fs from 'fs';

fs.readdirSync = jest.fn();

describe('readdirSync', () => {
  it('t1', () => {
    (fs.readdirSync as jest.MockedFunction<any>).mockReturnValueOnce(['Y']);
    const actualValue = readdirSync('X');
    expect(actualValue).toEqual(['Y']);
    expect(fs.readdirSync).toBeCalledWith('X');
  });

  it('t2', () => {
    (fs.readdirSync as jest.MockedFunction<any>).mockReturnValueOnce(['Z']);
    const actualValue = readdirSync('T');
    expect(actualValue).toEqual(['Z']);
    expect(fs.readdirSync).toBeCalledWith('T');
  });
});

 PASS  src/stackoverflow/46911799/index.spec.ts
  readdirSync
    ✓ t1 (8ms)
    ✓ t2 (1ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        4.917s, estimated 5s

更新

您也可以使用jest.fn().mockImplementation()

单元测试,

  1. 如果路径为X,则返回Y

  2. 如果路径为T,则返回Z

import { readdirSync } from './';
import fs from 'fs';

fs.readdirSync = jest.fn().mockImplementation(path => {
  switch (path) {
    case 'X':
      return ['Y'];
    case 'T':
      return ['Z'];
  }
});

describe('readdirSync', () => {
  it('t3', () => {
    const actualValue = readdirSync('X');
    expect(actualValue).toEqual(['Y']);
    expect(fs.readdirSync).toBeCalledWith('X');
  });

  it('t4', () => {
    const actualValue = readdirSync('T');
    expect(actualValue).toEqual(['Z']);
    expect(fs.readdirSync).toBeCalledWith('T');
  });
});

单元测试结果:

 PASS  src/stackoverflow/46911799/index-2.spec.ts
  readdirSync
    ✓ t3 (5ms)
    ✓ t4 (1ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        4.345s
相关问题