Заглушення методу класу за допомогою 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/ ) для вищезазначеного коду та jsFiddle для питання SO, про який я згадував ( http://jsfiddle.net/pebreo/9mK5d/1/ ).

Я переконався, що включив sinon до Зовнішніх ресурсів у jsFiddle та навіть jQuery 1.9. Що я роблю неправильно?

Відповіді:


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

sinon.stub (Датчик, "sample_pressure", function () {return 0})
понеділок74

Це в моїй відповіді, тому що оригінальне запитання було спеціально поставлене про це. Зважаючи на те, що моя відповідь не пропонує це як правильний підхід для початку, я не впевнений, що ви просите мене змінити. .returns(0)вже робить те саме, що і .callFake(() => 0).
loganfsmyth

1
Не здається, що returnsце застаріло. sinonjs.org/releases/v3.0.0/stubs . @ danday74, будь ласка, надайте посилання.
allenhwkim

2
@ danday74 .stubз функцією як третій аргумент видалено: github.com/sinonjs/sinon/blob/master/lib/sinon/stub.js#L17 У цьому немає нічого поганого .returnsабо .callsFake, отже, немає нічого поганого в цій відповіді.
loganfsmyth

52

Верхня відповідь застаріла. Тепер вам слід використовувати:

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

4
Було б чудово, якщо ви могли б згадати конкретну версію для вашого згаданого методу, коли до цього додано, sinonjsтобто callsFake()для старих версій, як це можна знехтувати?
aitchkhan

3
Під час використання модулів ES6: я створюю заглушку YourClass.get () у тестовому проекті. Тест викликає інший модуль, який імпортує YourClass. Чи буде модуль YourClass.get () поважати заглушку? Якщо ні, чи є рішення?
Учень

1
Ваші рішення працюють на мене. Я хотів би, якщо я дам вам більше очок: D Дякую.
Рубель хасан

5

Я зіткнувся з тією ж помилкою, намагаючись знущатися над методом класу CoffeeScript за допомогою Sinon.

Дано такий клас:

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

Ви можете замінити його метод шпигуном таким чином:

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

# ...

assert.ok(mySpy.called)

Просто замініть spyна stubабо mockза потребою.

Зауважте, що вам потрібно буде замінити assert.okбудь-яке твердження, яке має ваша тестова основа.


2

Дякуємо @loganfsmyth за пораду. Мені вдалося змусити заглушку працювати над методом класу Ембер таким:

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

3
Це коментар. Починається з подяки ще однією відповіддю і закінчується дублюванням її коду.
Michelpm

5
Не схоже на дублювання - тут є Foo.prototype.constructor, де, як і в оригінальній відповіді Sensor.prototype. Потім знову Foo.prototype.constructorне працює для мене. :)
shaunc
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.