Sinonjs如何存根依赖注入class?
Sinonjs how to stub dependency injection class?
我在下面编写了示例代码(从我的实际代码实现中进行了简化),这个简化版本的主要思想是了解如何对 class 进行单元测试
我有 Sensor
class 依赖注入到 Context
class,这个 Sensor
将从一些 IO
端口获取数据.
传感器数据将在 ComputeSensor
class 处与预期值进行比较,并将 report
键插入 context.report
对象。
我可以知道如何存根或模拟 Sensor
class,以便我可以创建一个假值来测试代码吗?
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,
}
或者我可以写一个模拟 class 如下..但我认为 Sinon 可以做到..
class MockSensor {
getData() {
return {
heat: 123,
speed: 321
}
}
}
希望我理解正确。
您可以存根方法,因此当有 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();
});
});
希望这有助于澄清。
我在下面编写了示例代码(从我的实际代码实现中进行了简化),这个简化版本的主要思想是了解如何对 class 进行单元测试
我有 Sensor
class 依赖注入到 Context
class,这个 Sensor
将从一些 IO
端口获取数据.
传感器数据将在 ComputeSensor
class 处与预期值进行比较,并将 report
键插入 context.report
对象。
我可以知道如何存根或模拟 Sensor
class,以便我可以创建一个假值来测试代码吗?
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,
}
或者我可以写一个模拟 class 如下..但我认为 Sinon 可以做到..
class MockSensor {
getData() {
return {
heat: 123,
speed: 321
}
}
}
希望我理解正确。
您可以存根方法,因此当有 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();
});
});
希望这有助于澄清。