web-dev-qa-db-ja.com

Sinon.jsでクラスメソッドをスタブする

Sinon.jsを使用してメソッドをスタブしようとしていますが、次のエラーが表示されます。

Uncaught TypeError: Attempted to wrap undefined property sample_pressure as function

私もこの質問に行き( sinon.jsのクラスのスタブやモック? )、コードをコピーして貼り付けましたが、同じエラーが発生します。

ここに私のコードがあります:

Sensor = (function() {
  // A simple Sensor class

  // Constructor
  function Sensor(pressure) {
    this.pressure = pressure;
  }

  Sensor.prototype.sample_pressure = function() {
    return this.pressure;
  };

  return Sensor;

})();

// Doesn't work
var stub_sens = sinon.stub(Sensor, "sample_pressure").returns(0);

// Doesn't work
var stub_sens = sinon.stub(Sensor, "sample_pressure", function() {return 0});

// Never gets this far
console.log(stub_sens.sample_pressure());

上記のコードのjsFiddle( http://jsfiddle.net/pebreo/wyg5f/5/ )と、前述のSO質問のjsFiddle(- http://jsfiddle.net/pebreo/9mK5d/1/ )。

JsFiddleおよびjQuery 1.9のExternal Resourcesにsinonを含めるようにしました。私は何を間違えていますか?

84
Paul

コードはSensorで関数をスタブしようとしていますが、Sensor.prototypeで関数を定義しています。

sinon.stub(Sensor, "sample_pressure", function() {return 0})

本質的にこれと同じです:

Sensor["sample_pressure"] = function() {return 0};

しかし、Sensor["sample_pressure"]が存在しないことを確認するには十分に賢いです。

したがって、あなたがしたいことは次のようなものです:

// Stub the prototype's function so that there is a spy on any new instance
// of Sensor that is created. Kind of overkill.
sinon.stub(Sensor.prototype, "sample_pressure").returns(0);

var sensor = new Sensor();
console.log(sensor.sample_pressure());

または

// Stub the function on a single instance of 'Sensor'.
var sensor = new Sensor();
sinon.stub(sensor, "sample_pressure").returns(0);

console.log(sensor.sample_pressure());

または

// Create a whole fake instance of 'Sensor' with none of the class's logic.
var sensor = sinon.createStubInstance(Sensor);
console.log(sensor.sample_pressure());
141
loganfsmyth

一番上の答えは非推奨です。次を使用する必要があります。

sinon.stub(YourClass.prototype, 'myMethod').callsFake(() => {
    return {}
})

または静的メソッドの場合:

sinon.stub(YourClass, 'myStaticMethod').callsFake(() => {
    return {}
})

または、単純な場合には、リターンのみを使用します。

sinon.stub(YourClass.prototype, 'myMethod').returns({})

sinon.stub(YourClass, 'myStaticMethod').returns({})

または、インスタンスのメソッドをスタブ化する場合:

const yourClassInstance = new YourClass();
sinon.stub(yourClassInstance, 'myMethod').returns({})
36
danday74

Sinonを使用してCoffeeScriptクラスのメソッドをモックしようとすると、同じエラーが発生しました。

このようなクラスが与えられた場合:

class MyClass
  myMethod: ->
    # do stuff ...

次の方法で、メソッドをスパイに置き換えることができます。

mySpy = sinon.spy(MyClass.prototype, "myMethod")

# ...

assert.ok(mySpy.called)

必要に応じて、spystubまたはmockに置き換えるだけです。

assert.okをテストフレームワークのアサーションに置き換える必要があることに注意してください。

3
Nathan Arthur

ヒントを提供してくれた@loganfsmythに感謝します。次のようなEmberクラスメソッドでスタブを動作させることができました。

sinon.stub(Foo.prototype.constructor, 'find').returns([foo, foo]);
expect(Foo.find()).to.have.length(2)
2
Scott Nedderman