Mock a dependency's constructor Jest

怎甘沉沦 提交于 2019-12-31 12:30:14

问题


I'm a newbie to Jest. I've managed to mock my own stuff, but seem to be stuck mocking a module. Specifically constructors.

usage.js

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

I'd like to do something like this in the tests.

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

AWS.CloudWatch = jest.fn( (props) => new FakeMetrics())

However when I come to use it in usage.js the cw is a mockConstructor not a FakeMetrics

I realise that my approach might be 'less than idiomatic' so I'd be greatful for any pointers.

This is a minimal example https://github.com/ollyjshaw/jest_constructor_so

npm install -g jest

jest


回答1:


The problem is how a module is being mocked. As the reference states,

Mocks a module with an auto-mocked version when it is being required. <...> Returns the jest object for chaining.

AWS is not module object but jest object, and assigning AWS.CloudFormation will affect nothing.

Also, it's CloudWatch in one place and CloudFormation in another.

Testing framework doesn't require to reinvent mock functions, they are already there. It should be something like:

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

And asserted like:

expect(fakePutMetricData).toHaveBeenCalledTimes(1);



回答2:


Above answer works. However, after some time working with jest I would just use the mockImplementation functionality which is useful for mocking constructors.

Below code could be an example:

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);
});

Note that in the example the new CloudWatch() just returns an empty object.




回答3:


According to the documentation mockImplementation can also be used to mock class constructors:

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

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

const some = new SomeClass();
some.m('a', 'b');
console.log('Calls to m: ', mMock.mock.calls);


来源:https://stackoverflow.com/questions/47606545/mock-a-dependencys-constructor-jest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!