Sinon.jsによるクラスメソッドのスタブ


99

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 にsinonを含めることを確認しました。何が悪いのですか?

回答:


155

あなたのコードはで関数をスタブしようとして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());

1
廃止予定のものはどれですか?
loganfsmyth 2017

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

元の質問が具体的にそれについて尋ねたので、それは私の答えの中にあります。私の答えがそれを始めるための正しいアプローチとしてそれを示唆していないので、私があなたに何を変更するように求めているのかわかりません。.returns(0)はすでにと同じことを行い.callFake(() => 0)ます。
loganfsmyth 2017

1
returns廃止予定ではないようです。sinonjs.org/releases/v3.0.0/stubs。@ danday74、参照を提供してください。
allenhwkim 2017

2
@ danday74 .stub三番目の引数としての機能を持つが削除されます。github.com/sinonjs/sinon/blob/master/lib/sinon/stub.js#L17はと何も間違ってあります.returns.callsFakeので、この答えで何も間違っています。
loganfsmyth 2017

52

上位の回答は非推奨です。あなたは今使うべきです:

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

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

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

または、単純な場合は単にreturnを使用します。

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

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

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

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

4
これをするために追加されたとき、あなたの言った方法のための特定のバージョンに言及することができればそれは素晴らしいことだsinonjs、つまりcallsFake()どのようにこれは廃止することができ、古いバージョンのために、さらに?
aitchkhan 2017年

3
ES6モジュールを使用する場合:テストプロジェクトでYourClass.get()のスタブを作成しています。テストでは、YourClassをインポートする別のモジュールを呼び出します。モジュールYourClass.get()はスタブを尊重しますか?そうでない場合、解決策はありますか?
学習者

1
あなたの解決策は私のために働きます。私はあなたにもっとポイントを与えたいと思います:Dありがとう。
ルベルハサン

5

Sinonを使用してCoffeeScriptクラスのメソッドをモックしようとして同じエラーに遭遇しました。

次のようなクラスがあるとします。

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

次のようにして、そのメソッドをスパイに置き換えることができます。

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

# ...

assert.ok(mySpy.called)

必要に応じspystubまたはと交換してくださいmock

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


2

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

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

3
これはコメントです。別の回答への感謝から始まり、コードの複製で終わります。
michelpm 2015

5
重複のようには見えません-ここにありますがFoo.prototype.constructor、元の答えのようにありSensor.prototypeます。それでもFoo.prototype.constructor、私にはうまくいきません。:)
ショーン2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.