javascript 如何测试在触发事件后是否调用了函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18321993/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to test that a function has been called after an event was fired?
提问by JJD
There is custom event fired in the FooView..
FooView.. 中触发了自定义事件
// views/foo_view.js
this.trigger("something:happened");
The associated FooControllerbinds a handler to take care of the event ...
关联FooController绑定一个处理程序来处理事件......
// controller/foo_controller.js
initialize: function() {
this.fooView = new FooView();
this.fooView.bind("something:happened", this.onSomethingHappened, this);
}
onSomethingHappened: function(event) {
// Do something else.
}
To test the event handling I would write the following test for Jasmine:
为了测试事件处理,我将为Jasmine编写以下测试:
it("should do something else when something happens", function() {
var fooController = new FooController();
spyOn(fooController, "onSomethingHappened");
fooController.fooView.trigger("something:happened");
expect(fooController.onSomethingHappened).toHaveBeenCalled();
});
Though, the test fails ..
虽然,测试失败..
FooView should do something else when something happens.
Expected spy onSomethingHappened to have been called.
Error: Expected spy onSomethingHappened to have been called.
at new jasmine.ExpectationResult (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:114:32)
at null.toHaveBeenCalled (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:1235:29)
at null.<anonymous> (http://localhost:8888/assets/foo_spec.js?body=true:225:47)
at jasmine.Block.execute (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:1064:17)
at jasmine.Queue.next_ (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2096:31)
at jasmine.Queue.start (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2049:8)
at jasmine.Spec.execute (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2376:14)
at jasmine.Queue.next_ (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2096:31)
at onComplete (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2092:18)
at jasmine.Spec.finish (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2350:5)
Does the test fail because the event takes longer than the expectation to excute?
测试失败是否因为事件执行的时间比预期的要长?
回答by Andreas K?berle
The problem is that you spy on a function after the function was bound to the event. When jasmine create a spy it will replace the function you spy on with another function.
问题是您在函数绑定到事件后监视了该函数。当 jasmine 创建一个 spy 时,它将用另一个函数替换您监视的函数。
So what happens here, is that the original function is bound to the event
那么这里发生的事情是原始函数绑定到事件
this.fooView.bind("something:happened", this.onSomethingHappened, this);
After that, the original function is replaced by the spy, but that will not have any effect on the function you pass to the bindfunction.
之后,原始函数被 spy 替换,但这不会对您传递给bind函数的函数产生任何影响。
The solution for that is to spy FooController.prototype.onSomethingHappenedbefore you create a new instance:
解决方案是FooController.prototype.onSomethingHappened在创建新实例之前进行监视:
it("should do something else when something happens", function() {
var onSomethingHappenedSpy = spyOn(FooController.prototype, "onSomethingHappened");
var fooController = new FooController();
fooController.fooView.trigger("something:happened");
expect(onSomethingHappenedSpy).toHaveBeenCalled();
});

