web-dev-qa-db-fra.com

Simulez le constructeur d'une dépendance

Je suis un débutant à Jest. J'ai réussi à me moquer de mes propres affaires, mais il semble que je sois bloqué pour me moquer d'un module. Plus précisément les constructeurs.

utilisation.js

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

Je voudrais faire quelque chose comme ça dans les tests. 

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

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

Cependant, lorsque je viens de l'utiliser dans usage.js, le cw est un mockConstructor pas un FakeMetrics

Je me rends compte que mon approche est peut-être moins que idiomatique, alors je serais reconnaissant pour tous les indicateurs.

Ceci est un exemple minimal https://github.com/ollyjshaw/jest_constructor_so

npm install -g jest

jest

11
Oliver Shaw

Le problème est de savoir comment un module est simulé. Comme la référence déclare,

Mock un module avec une version auto-mocked quand il est requis. <...> Retourne l'objet Jest pour le chaînage.

AWS n'est pas un objet de module mais un objet jest et l'affectation de AWS.CloudFormation n'affectera rien.

De plus, c'est CloudWatch à un endroit et CloudFormation à un autre.

La structure de test ne nécessite pas de réinventer les fonctions fictives, elles sont déjà là. Cela devrait être quelque chose comme:

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

Et affirmé comme:

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

La réponse ci-dessus fonctionne. Cependant, après un certain temps de travail avec jest , je voudrais simplement utiliser la fonctionnalité mockImplementation qui est utile pour se moquer des constructeurs.

Le code ci-dessous pourrait être un exemple:

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

Notez que dans l'exemple, le new CloudWatch () ne renvoie qu'un objet vide. 

1
kimy82