Sinonjs如何对依赖注入类进行存根?

3
我有如下示例代码(简化自实际代码实现),其主要目的是了解如何为单元测试打桩。
我有一个名为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个回答

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

});

希望这可以帮助您更加清晰地理解。

如果使用sinon.createStubInstance,我该如何存根方法? - Tim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接