模拟一个依赖的构造函数Jest

Oli*_*haw 17 javascript node.js ecmascript-6 jestjs aws-sdk

我是Jest的新手.我已经设法模仿我自己的东西,但似乎被模仿一个模块.特别是构造者.

usage.js

const AWS = require("aws-sdk")
cw = new AWS.CloudWatch({apiVersion: "2010-08-01"})
...
function myMetrics(params) { 
  cw.putMetricData(params, function(err, data){})
}
Run Code Online (Sandbox Code Playgroud)

我想在测试中做这样的事情.

const AWS = jest.mock("aws-sdk")
class FakeMetrics {
  constructor() {}
  putMetricData(foo,callback) {
    callback(null, "yay!")
  }
}

AWS.CloudWatch = jest.fn( (props) => new FakeMetrics())
Run Code Online (Sandbox Code Playgroud)

但是,当我来usage.jscw 使用它是一个mockConstructor不是FakeMetrics

我意识到我的方法可能"不是惯用的"所以我会对任何指针感到满意.

这是一个最小的例子https://github.com/ollyjshaw/jest_constructor_so

npm install -g jest

jest

Est*_*ask 12

问题是如何模拟模块.作为参考说明,

在需要时模拟具有自动模拟版本的模块.<...>返回链接的jest对象.

AWS不是模块对象而是jest对象,分配AWS.CloudFormation不会影响任何东西.

此外,它CloudWatch在一个地方,CloudFormation在另一个地方.

测试框架不需要重新发明模拟函数,它们已经存在.它应该是这样的:

const AWS = require("aws-sdk");
const fakePutMetricData = jest.fn()
const FakeCloudWatch = jest.fn(() => ({
    putMetricData: fakePutMetricData
}));                        
AWS.CloudWatch = FakeCloudWatch;
Run Code Online (Sandbox Code Playgroud)

断言如下:

expect(fakePutMetricData).toHaveBeenCalledTimes(1);
Run Code Online (Sandbox Code Playgroud)


kim*_*y82 8

以上答案有效。但是,经过一段时间的玩笑之后,我将只使用对模拟构造函数有用的mockImplementation功能。

下面的代码可能是一个示例:

import * as AWS from 'aws-sdk';

jest.mock('aws-sdk', ()=> {
    return {
        CloudWatch : jest.fn().mockImplementation(() => { return {} })
    }
});

test('AWS.CloudWatch is callled', () => {
    new AWS.CloudWatch();
    expect(AWS.CloudWatch).toHaveBeenCalledTimes(1);
});
Run Code Online (Sandbox Code Playgroud)

请注意,在示例中,新的CloudWatch()仅返回一个空对象。


Dev*_*avo 7

根据文档 mockImplementation还可以用于模拟类构造函数:

// SomeClass.js
module.exports = class SomeClass {
  method(a, b) {}
};

// OtherModule.test.js
jest.mock('./SomeClass'); // this happens automatically with automocking
const SomeClass = require('./SomeClass');
const mockMethod= jest.fn();
SomeClass.mockImplementation(() => {
  return {
    method: mockMethod,
  };
});

const some = new SomeClass();
some.method('a', 'b');
console.log('Calls to method: ', mockMethod.mock.calls);
Run Code Online (Sandbox Code Playgroud)

如果你的类构造函数有参数,你可以jest.fn()作为参数传递(例如const some = new SomeClass(jest.fn(), jest.fn());