Jasmine - 触发事件不起作用
Jasmine - trigger event not working
我要测试的代码:
$(".toggle_item").on("change", function() {
console.log("change triggered")
item_name = $(this).data("name");
value = $(this).prop("checked");
if (Item.isValid(item_name) && cartModule.isUnique(item_name)) {
cartModule.toggleItem(item_name, value);
}
})
茉莉规格:
describe("changing toggle item", function() {
beforeEach(function() {
console.log("in spec")
affix(".toggle_item[data-name='ladder']")
spyOn(cartModule, "isUnique")
spyOn(Item, "isValid")
$(".toggle_item").trigger("change")
})
it("should check item for validity & cart for uniqueness", function() {
expect(Item.isValid).toHaveBeenCalledWith("ladder")
expect(cartModule.isUnique).toHaveBeenCalledWith("ladder")
})
})
控制台日志输出表明触发器没有触发。日志输出:
> "in spec"
FWIW:
- 我试过同时使用
affix
和 loadFixtures
- 我试过同时使用
$(".toggle_item").on("change"...
和 $(".toggle_item").change...
Gem 列表:
jasmine (2.7.0)
jasmine-core (2.8.0, 2.7.0)
jasmine-jquery-rails (2.0.3)
jasmine-rails (0.14.1)
** 更新答案:2018-02-03**
这里的根本问题是您的代码 运行ning 太早了,在您的设备设置之前。这与在所有测试之前加载代码不同。您需要能够控制代码 运行s 在 loaded.
之后的时间
这更多地与您如何编写代码以便对其进行测试有关,并且在很大程度上独立于实际用于测试的工具和库。
这是一个例子:
// There is no way to test this expression - it runs as soon as it is loaded
1 + 2
// This is similar to the line above - it tries to add the event listener as soon
// as the line of code is encountered. If you haven't set up fixtures before this line is run
// then you can't test it.
$('.toggle_item').on('change', ...);
// Here is an example of code that is testable
// It is testable because we have separated out the loading of the code
// from the **invocation** of the code.
function add(){
// i.e. This expression will only run when `add()` is invoked.
return 1 + 2;
}
// Here is an example that adds a bit more control over when the event listeners are added.
$(function(){
// This expression runs when `$.ready` is fired (aka `DOMContentLoaded`)
// If you can delay `$.ready` until your fixtures are set up then this will work.
$('.toggle_item').on('change', ...);
})
your linked answer中的解释不太正确。 $('.selector').click(...)
只是 $('.selector').on('click', ...)
的别名或缩写,因此更改为不会有任何区别 - 它们在功能上完全相同。
答案在那种情况下实际有效的原因是因为事件侦听器是在 $.ready()
事件中添加的,而不是在加载代码后立即添加。
这是运行宁这个的区别:
console.log('1 before');
console.log('2 middle');
console.log('3 after');
结果:
> 1 before
> 2 middle
> 3 after
并且运行宁此:
console.log('1 before');
$(function(){
console.log('2 middle');
});
console.log('3 after');
结果:
> 1 before
> 3 after
> 2 middle
另一个可能对您有帮助的工具是 delegated event listeners。
基本上,您将单个事件侦听器添加到 DOM 树的更上方的元素,该树侦听来自特定子选择器的事件。
例如:
$(function(){
$(document).on('change', '.toggle_item', function(){
});
})
这样做的好处是可以提前添加事件侦听器,.toggle_item
之前的事件存在,但是一旦添加了元素就会触发侦听器。
使用事件委托有一些注意事项(例如,使用 event.preventDefault()
或 event.stopPropagation()
时),但它们仍然是一个非常有用的工具。
原回答
在您的测试代码中,当添加事件侦听器时,您是否能够control/delay?
我怀疑您的代码试图在 affix(".toggle_item[data-name='ladder']")
语句在您的测试中 运行 之前将事件侦听器添加到 .toggle_item
。
console.log('Adding listener')
$(".toggle_item").on("change", function() {
console.log("change triggered")
...
});
如果你得到:
你就会知道它出了问题
> "Adding listener"
> "in spec"
而不是我们想要的:
> "in spec"
> "Adding listener"
我要测试的代码:
$(".toggle_item").on("change", function() {
console.log("change triggered")
item_name = $(this).data("name");
value = $(this).prop("checked");
if (Item.isValid(item_name) && cartModule.isUnique(item_name)) {
cartModule.toggleItem(item_name, value);
}
})
茉莉规格:
describe("changing toggle item", function() {
beforeEach(function() {
console.log("in spec")
affix(".toggle_item[data-name='ladder']")
spyOn(cartModule, "isUnique")
spyOn(Item, "isValid")
$(".toggle_item").trigger("change")
})
it("should check item for validity & cart for uniqueness", function() {
expect(Item.isValid).toHaveBeenCalledWith("ladder")
expect(cartModule.isUnique).toHaveBeenCalledWith("ladder")
})
})
控制台日志输出表明触发器没有触发。日志输出:
> "in spec"
FWIW:
- 我试过同时使用
affix
和loadFixtures
- 我试过同时使用
$(".toggle_item").on("change"...
和$(".toggle_item").change...
Gem 列表:
jasmine (2.7.0)
jasmine-core (2.8.0, 2.7.0)
jasmine-jquery-rails (2.0.3)
jasmine-rails (0.14.1)
** 更新答案:2018-02-03**
这里的根本问题是您的代码 运行ning 太早了,在您的设备设置之前。这与在所有测试之前加载代码不同。您需要能够控制代码 运行s 在 loaded.
之后的时间这更多地与您如何编写代码以便对其进行测试有关,并且在很大程度上独立于实际用于测试的工具和库。
这是一个例子:
// There is no way to test this expression - it runs as soon as it is loaded
1 + 2
// This is similar to the line above - it tries to add the event listener as soon
// as the line of code is encountered. If you haven't set up fixtures before this line is run
// then you can't test it.
$('.toggle_item').on('change', ...);
// Here is an example of code that is testable
// It is testable because we have separated out the loading of the code
// from the **invocation** of the code.
function add(){
// i.e. This expression will only run when `add()` is invoked.
return 1 + 2;
}
// Here is an example that adds a bit more control over when the event listeners are added.
$(function(){
// This expression runs when `$.ready` is fired (aka `DOMContentLoaded`)
// If you can delay `$.ready` until your fixtures are set up then this will work.
$('.toggle_item').on('change', ...);
})
your linked answer中的解释不太正确。 $('.selector').click(...)
只是 $('.selector').on('click', ...)
的别名或缩写,因此更改为不会有任何区别 - 它们在功能上完全相同。
答案在那种情况下实际有效的原因是因为事件侦听器是在 $.ready()
事件中添加的,而不是在加载代码后立即添加。
这是运行宁这个的区别:
console.log('1 before');
console.log('2 middle');
console.log('3 after');
结果:
> 1 before
> 2 middle
> 3 after
并且运行宁此:
console.log('1 before');
$(function(){
console.log('2 middle');
});
console.log('3 after');
结果:
> 1 before
> 3 after
> 2 middle
另一个可能对您有帮助的工具是 delegated event listeners。
基本上,您将单个事件侦听器添加到 DOM 树的更上方的元素,该树侦听来自特定子选择器的事件。
例如:
$(function(){
$(document).on('change', '.toggle_item', function(){
});
})
这样做的好处是可以提前添加事件侦听器,.toggle_item
之前的事件存在,但是一旦添加了元素就会触发侦听器。
使用事件委托有一些注意事项(例如,使用 event.preventDefault()
或 event.stopPropagation()
时),但它们仍然是一个非常有用的工具。
原回答
在您的测试代码中,当添加事件侦听器时,您是否能够control/delay?
我怀疑您的代码试图在 affix(".toggle_item[data-name='ladder']")
语句在您的测试中 运行 之前将事件侦听器添加到 .toggle_item
。
console.log('Adding listener')
$(".toggle_item").on("change", function() {
console.log("change triggered")
...
});
如果你得到:
你就会知道它出了问题> "Adding listener"
> "in spec"
而不是我们想要的:
> "in spec"
> "Adding listener"