Sinonjs如何存根依赖注入类?

时间:2017-02-19 03:06:11

标签: javascript unit-testing mocha sinon stub

我有下面编写的示例代码(从我的实际代码实现中简化),这个简化版本的主要思想是了解如何将类存根用于单元测试

我有Sensor类,它是注入Context类的依赖项,此Sensor将从某个IO端口获取数据。

传感器数据将在ComputeSensor类中进行比较以获得预期值,并将report键插入context.report对象。

我可以知道如何存根或模拟Sensor类,所以我可以创建一个伪值来测试代码吗?

class Sensor {
  getData() {        
    return {
      heat: this.getHeatSensor(), // get data from some IO
      speed: this.getSpeedSensor() // get data from some IO
    }
  }
}

class Context {
  constructor(sensor) {
    this.report = {};
    this.sensor = sensor;
    this.computeSensor = new ComputeSensor();
  }

  execute() {
    this.computeSensor.compute(this, this.sensor.getData());
  }
}

class ComputeSensor {
  compute(context, sensorData) {
    if (sensorData.heat === 123
      && sensorData.speed === 321) 
    {
      context.report = {
        sensor: 'ok'
      }  
    }
  }
}

const sensor = new Sensor();
const context = new Context(sensor);
context.execute();
console.log(context.report) // { sensor: 'ok }

也许所需的存根代码会是这样的?

const stubSensor = sinon.createStubInstance(Sensor);
// Inject the stub return value here?
stubSensor.getData() = {
  heat: 123,
  speed: 321,
}

或者我可以写下一个模拟课程。但我认为Sinon可以做到这一点..

class MockSensor {
      getData() {
             return {
                   heat: 123,
                   speed: 321
             }
      }
 }

1 个答案:

答案 0 :(得分:3)

我希望我理解正确。
您可以存根方法,因此当存在IO调用时,将返回固定值。
例如

import {expect} from 'chai';
import sinon from 'sinon';

class Sensor {
    getHeatSensor(){

    }
    getSpeedSensor(){

    }
    getData() {
        return {
            heat: this.getHeatSensor(), // get data from some IO
            speed: this.getSpeedSensor() // get data from some IO
        }
    }
}

class Context {
    constructor(sensor) {
        this.report = {};
        this.sensor = sensor;
        this.computeSensor = new ComputeSensor();
    }

    execute() {
        this.computeSensor.compute(this, this.sensor.getData());
    }
}

class ComputeSensor {
    compute(context, sensorData) {
        if (sensorData.heat === 123 && sensorData.speed === 321) {
            context.report = {
                sensor: 'ok'
            }
        }
    }
}

describe('Test Sensor', () => {
    it('should compute value ', () => {
        const sensor = new Sensor;
        sinon.stub(sensor,'getHeatSensor').returns(123);
        sinon.stub(sensor,'getSpeedSensor').returns(321);

        const context = new Context(sensor);
        context.execute();

        console.log(context.report);

        expect(context.report).to.deep.equal({sensor:'ok'})
        sensor.getHeatSensor.restore(); //don't forget to restore
        sensor.getSpeedSensor.restore();
    });

    it('should return empty object ', () => {
        const sensor = new Sensor;
        sinon.stub(sensor,'getHeatSensor').returns(99);
        sinon.stub(sensor,'getSpeedSensor').returns(84);

        const context = new Context(sensor);
        context.execute();

        console.log(context.report);

        expect(context.report).to.deep.equal({})
        sensor.getHeatSensor.restore();
        sensor.getSpeedSensor.restore();
    });

});

希望得到这个帮助,澄清一下。