简体   繁体   English

使用Sinon将存根依赖项注入到es6类中

[英]Injecting a stubbed dependency into an es6 class with Sinon

I have the following modules: 我有以下模块:

const rp = require('request-promise');

// dummies.repository.js 

exports.getDummiesData = () => {
  const options = {
    url: 'https://api.github.com/users',
    headers: {
      'User-Agent': 'Request-Promise',
    },
    json: true
  };
  return rp(options)
  .then(r => r)
  .catch(err => { throw err; });

}

The above file is a dependency to a class that I would like to test. 上面的文件是我要测试的类的依赖项。 I inject it to the below class via its constructor like so: 我像这样通过其构造函数将其注入以下类:

// dummies.service.js
const Dummies = require('./dummies.model');
class DummiesService {
  constructor(dummiesRepository) {
  this.dummiesRepository = dummiesRepository;
 }

 getDummies() {
    return new Promise((resolve, reject) => {
        this.dummiesRepository.getDummiesData()
        .then((response) => {
        // business logic
        const dummies = response.map(d => new Dummies(d));
        resolve(dummies);
       })
       .catch((response) => {
         reject(response);
       });
   });
  }
 }
module.exports = DummiesService;

In the above, I want to test the method getDummies with sinon. 在上文中,我想测试方法getDummies与兴农。 My approach so far has been to stub out the dummiesRepository and inject that to my dummies service during instantiation, but I am getting an error. 到目前为止,我的方法是将dummiesRepository存根,并在实例化期间将其注入到我的dummiesRepository服务中,但是我遇到了错误。 Here is how my test looks: 这是我的测试结果:

const DummiesService = require('../dummies.service');
const dummiesRepository = require('../dummies.repository');
let dummiesRepositoryStub;

afterEach(() => {
   if(dummiesRepositoryStub){
     dummiesRepositoryStub.restore();
   }
});

describe('unit: dummies.service - when getting dummies data', () => {
  it('it should resolve and return dummies data', () => {
    const dummiesResponse = [
      { id: 1, login: 'dummy1', additionalData: 'data' },
      { id: 2, login: 'dummy2', additionalData: 'data' },
      { id: 3, login: 'dummy3', additionalData: 'data' },
    ];

    dummiesRepositoryStub = sinon
      .stub(dummiesRepository, 'getDummiesData')
      .resolves(dummiesResponse);

    dummiesService = new DummiesService(dummiesRepositoryStub);
    // act + assert
    return dummiesService.getDummies()
      .then((response) => {
        chai.expect(dummiesRepositoryStub.called).to.equal(true);
        chai.expect(response).to.deep.equal(dummiesTransformedModel);
      });
  });

This test fails with error TypeError: this.dummiesRepository.getDummiesData is not a function . 该测试失败,并显示错误TypeError: this.dummiesRepository.getDummiesData is not a function I am not sure why this is not working, I injected a stub implementation of dummiesRepository to the DummiesService class. 我不确定为什么这不起作用,我将dummiesRepository的存根实现注入了DummiesService类。 Please assist. 请协助。

I could not find a way to do constructor injection in the above code, but I found a work around to allow sinon to stub my method. 我在上面的代码中找不到一种进行构造函数注入的方法,但是我找到了一种解决方法,允许sinon对我的方法进行存根。

I had to remove dummyRepository from being a constructor dependency to just using require to include it. 我不得不将dummyRepository从构造函数依赖项中删除,而仅使用require包含它。 If the code looks as follows 如果代码如下所示

const Dummies = require('./dummies.model');
const dummiesRepository = require('./dummies.repository');

class DummiesService {
  constructor() {
    this.dummiesRepository = dummiesRepository;
  }
  getDummies() {
    return new Promise((resolve, reject) => {
      this.dummiesRepository.getDummiesData()
        .then((response) => {
          // business logic
          const dummies = response.map(d => new Dummies(d));
          resolve(dummies);
        })
        .catch((response) => {
          reject(response);
        });
    });
  }
}

module.exports = DummiesService;

and the test is written the same as above, but instantiating DummyService without the dummyRepositoryStub as a parameter, everything works fine. 并且测试的编写方式与上面相同,但是实例化DummyService而不使用dummyRepositoryStub作为参数,一切正常。

This works, but I would still like to know if there is a way to inject the dependency via the constructor, because this approach requires me to refactor a lot of my code. 这行得通,但是我仍然想知道是否有一种通过构造函数注入依赖关系的方法,因为这种方法需要我重构很多代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM