Stubbing a class method ด้วย 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 ผมทำอะไรผิดหรือเปล่า?

คำตอบ:


156

รหัสของคุณพยายามที่จะหยุดการทำงานของฟังก์ชัน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 (Sensor, "sample_pressure", function () {return 0})
danday74

นั่นอยู่ในคำตอบของฉันเพราะคำถามเดิมถามเกี่ยวกับเรื่องนี้โดยเฉพาะ เนื่องจากคำตอบของฉันไม่ได้แนะนำว่าเป็นแนวทางที่ถูกต้องในการเริ่มต้นฉันไม่แน่ใจว่าคุณกำลังขอให้ฉันเปลี่ยนอะไร .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
จะดีมากถ้าคุณสามารถพูดถึงเวอร์ชันเฉพาะสำหรับวิธีการดังกล่าวของคุณเมื่อมีการเพิ่มเข้าไปในsinonjsie callsFake()นอกจากนี้สำหรับเวอร์ชันเก่าจะเลิกใช้งานได้อย่างไร
aitchkhan

3
เมื่อใช้โมดูล ES6: ฉันกำลังสร้างต้นขั้วของ YourClass.get () ในโครงการทดสอบ การทดสอบเรียกใช้โมดูลอื่นที่นำเข้า YourClass โมดูล YourClass.get () จะเคารพต้นขั้วหรือไม่ ถ้าไม่มีวิธีแก้ไขหรือไม่?
ผู้เรียน

1
โซลูชันของคุณใช้ได้ผลสำหรับฉัน ฉันหวังว่าฉันจะให้คะแนนคุณมากกว่านี้: D ขอบคุณ
Rubel hasan

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 สำหรับเคล็ดลับ ฉันสามารถทำให้ต้นขั้วทำงานกับเมธอดคลาส Ember ได้ดังนี้:

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.