Lưu trữ một phương thức lớp với Sinon.js


99

Tôi đang cố gắng khai báo một phương thức bằng sinon.js nhưng tôi gặp lỗi sau:

Uncaught TypeError: Attempted to wrap undefined property sample_pressure as function

Tôi cũng đã đi đến câu hỏi này ( Stubbing và / hoặc chế nhạo một lớp trong sinon.js? ) Và sao chép và dán mã nhưng tôi gặp lỗi tương tự.

Đây là mã của tôi:

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());

Đây là jsFiddle ( http://jsfiddle.net/pebreo/wyg5f/5/ ) cho đoạn mã trên và jsFiddle cho câu hỏi SO mà tôi đã đề cập ( http://jsfiddle.net/pebreo/9mK5d/1/ ).

Tôi đã đảm bảo bao gồm sinon trong Tài nguyên bên ngoài trong jsFiddle và thậm chí là jQuery 1.9. Tôi đang làm gì sai?

Câu trả lời:


155

Mã của bạn đang cố gắng khai thác một chức năng Sensor, nhưng bạn đã xác định chức năng trên Sensor.prototype.

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

về cơ bản giống như sau:

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

nhưng nó đủ thông minh để thấy rằng điều Sensor["sample_pressure"]đó không tồn tại.

Vì vậy, những gì bạn muốn làm là một cái gì đó như sau:

// 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());

hoặc là

// 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());

hoặc là

// 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
Thứ nào không được dùng nữa?
loganfsmyth

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

Đó là trong câu trả lời của tôi vì câu hỏi ban đầu đã hỏi cụ thể về nó. Cho rằng câu trả lời của tôi không gợi ý rằng đó là cách tiếp cận chính xác để bắt đầu, tôi không chắc bạn đang yêu cầu tôi thay đổi điều gì. .returns(0)đã làm điều tương tự như .callFake(() => 0).
loganfsmyth

1
Có vẻ như nó returnskhông bị phản đối. sinonjs.org/releases/v3.0.0/stubs . @ danday74, vui lòng cung cấp tài liệu tham khảo.
allenhwkim

2
@ danday74 .stubvới một hàm khi đối số thứ ba bị xóa: github.com/sinonjs/sinon/blob/master/lib/sinon/stub.js#L17 Không có gì sai với .returnshoặc .callsFake, vì vậy không có gì sai với câu trả lời này.
loganfsmyth

52

Câu trả lời hàng đầu không được dùng nữa. Bây giờ bạn nên sử dụng:

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

Hoặc đối với các phương thức tĩnh:

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

Hoặc đối với các trường hợp đơn giản, chỉ cần sử dụng trả về:

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

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

Hoặc nếu bạn muốn tạo một phương thức cho một ví dụ:

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

4
Sẽ thật tuyệt nếu bạn có thể đề cập đến phiên bản cụ thể cho phương pháp đã nói của bạn khi điều này được thêm vào, sinonjstức là callsFake()hơn nữa, đối với các phiên bản cũ hơn, điều này có thể không được dùng nữa?
aitchkhan

3
Khi sử dụng mô-đun ES6: Tôi đang tạo sơ khai của YourClass.get () trong một dự án thử nghiệm. Thử nghiệm gọi một mô-đun khác nhập YourClass. Mô-đun YourClass.get () có tôn trọng sơ khai không? Nếu không, có một giải pháp?
Người học

1
Giải pháp của bạn phù hợp với tôi. Tôi ước nếu tôi cho bạn nhiều điểm hơn: D Cảm ơn.
Rubel hasan

5

Tôi đã gặp phải lỗi tương tự khi cố gắng bắt chước một phương thức của một lớp CoffeeScript bằng cách sử dụng Sinon.

Cho một lớp như thế này:

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

Bạn có thể thay thế phương thức của nó bằng một phần mềm gián điệp theo cách này:

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

# ...

assert.ok(mySpy.called)

Chỉ cần thay thế spybằng stubhoặc mockkhi cần thiết.

Lưu ý rằng bạn sẽ cần thay thế assert.okbằng bất kỳ xác nhận nào mà khung thử nghiệm của bạn có.


2

Cảm ơn @loganfsmyth về mẹo. Tôi đã có thể lấy sơ khai để làm việc trên một phương thức lớp Ember như sau:

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

3
Đây là một bình luận. Bắt đầu bằng một câu cảm ơn cho một câu trả lời khác và kết thúc bằng một đoạn mã trùng lặp.
michelpm

5
Trông không giống như một sự trùng lặp - ở đây có Foo.prototype.constructor, nơi như trong câu trả lời ban đầu là có Sensor.prototype. Sau đó, một lần nữa, Foo.prototype.constructorkhông làm việc cho tôi. :)
shaunc
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.