webentwicklung-frage-antwort-db.com.de

Verspottet den Konstruktor Jest einer Abhängigkeit

Ich bin ein Neuling für Jest. Ich habe es geschafft, meine eigenen Sachen zu verspotten, aber ich scheine ein Modul zu verspotten. Speziell Konstruktoren.

usage.js

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

Ich möchte so etwas in den Tests machen. 

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

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

Wenn ich es jedoch in usage.js verwende, ist das cw eine mockConstructor und keine FakeMetrics

Mir ist klar, dass mein Ansatz "weniger als idiomatisch" sein könnte, also wäre ich für alle Hinweise dankbar.

Dies ist ein minimales Beispiel https://github.com/ollyjshaw/jest_constructor_so

npm install -g jest

jest

11
Oliver Shaw

Das Problem ist, wie ein Modul verspottet wird. Als die Referenz Zustände,

Verspottet ein Modul mit einer automatisch gespielten Version, wenn dies erforderlich ist. <...> Gibt das Scherzobjekt zur Verkettung zurück.

AWS ist kein Modulobjekt, sondern jest-Objekt, und die Zuweisung von AWS.CloudFormation beeinflusst nichts.

Es ist auch CloudWatch an einer Stelle und CloudFormation an einer anderen.

Beim Testen des Frameworks müssen die Scheinfunktionen nicht neu erfunden werden, sie sind bereits vorhanden. Es sollte so etwas sein wie:

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

Und behauptete wie:

expect(fakePutMetricData).toHaveBeenCalledTimes(1);
9
estus

Antwort oben funktioniert. Nach einiger Zeit mit jest würde ich jedoch einfach die mockImplementation -Funktionalität verwenden, die nützlich ist, um Konstruktoren zu simulieren.

Der folgende Code könnte ein Beispiel sein:

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

Beachten Sie, dass in diesem Beispiel new CloudWatch () nur ein leeres Objekt zurückgibt. 

1
kimy82

Gemäß der Dokumentation kannmockImplementation auch verwendet werden, um Klassenkonstruktoren zu verspotten:

// 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);
0
Developer Davo