断言函数已执行
Assert that a function was executed
我正在尝试对订阅 ko.observable
的 Knockout JS 扩展程序函数进行单元测试(当值更改时导致它变为 运行)。为了测试它是否正常工作,我需要验证扩展函数在 ko.observable
更改时是否已执行。
这是我目前的测试:
test("ko.extenders.addFieldTrackingGA", function () {
//arrange
var testObservable = ko.observable(1).extend({
addFieldTrackingGA: "Some button was clicked"
});
//act
testObservable(5);
//assert
});
我的问题是:如何断言 ko.extenders.addFieldTrackingGA 在 observable 更改时执行?
这是我要确认执行的代码:
敲除扩展:
ko.extenders.addFieldTrackingGA = function (target, option) {
target.subscribe(function (newValue) {
if (newValue) {
qb.Utils.Analytics().trackEvent(qb.Utils.Analytics().product,
"form click",
option,
false);
}
});
return target;
};
qb.analystics:
/**
* Event = e.g. 'trackEvent'
* Category = e.g. 'error_message_home'
* Action = fieldName
* Label = 'some message'
* ignoreMultiple = false | true | {blank} - if true, gtm actions that are fired more than once will be ignored, defaults to true.
*/
var _pushGTM = function (event, category, action, label, ignoreMultiple) {
if (typeof dataLayer !== 'undefined') { // Add test for dataLayer as breaking Qunit
ignoreMultiple = ignoreMultiple === undefined ? true : ignoreMultiple;
if (_.contains(pushedGTM, action + label) && ignoreMultiple) { // Make sure event doesn't get fired more than once, only fire it the first time
return;
}
var gtmObject = {
'event': event,
'eventDetails.category': category, // Push the value depending on the form (car/house/contents)
'eventDetails.action': action, // Push the form field name.(If there is no field name push "No_field"
'eventDetails.label': label // Please push the exact error string.
}
if (ignoreMultiple) {
pushedGTM.push(action + label);
}
_pushGTMObject(gtmObject);
}
}
您应该意识到您对扩展程序有相当大的依赖性:qb.analytics。目前你(副作用)也在测试,当你只想要测试一个单元:扩展器。
我可以给你至少三个基本选项来处理这个问题:
- 分解出
qb
上的依赖关系,并以某种方式将其注入到您的扩展器中。然后,您的测试可以注入有助于断言的模拟。
- 使用某种 spy/mock 框架,例如 SinonJS。我承认,由于缺乏使用 SinonJS 和类似框架的经验,我不能 100% 确定这种方法是否会奏效。
- 测试中的 Monkey 补丁
qb
以帮助进行断言。
后一种方法有点生硬,但很简单。它的工作原理如下:
(function() {
"use strict";
var trackEventFn = function() { };
QUnit.module("Mymodule", {
beforeEach: function() {
window.qb = {
Utils: {
Analytics: function() {
return { trackEvent: trackEventFn };
}
}
};
}
});
QUnit.test("ko.extenders.addFieldTrackingGA", function(assert) {
// arrange
var testObservable = ko.observable(1).extend({
addFieldTrackingGA: "Some button was clicked"
});
// prepare assertion
trackEventFn = function(prod, event, option, somebool) {
assert.ok(true);
// You can also assert on the argument values here
}
assert.expect(1); // Or more than 1, depending on the above
// act
testObservable(5);
});
}());
这是一个完整的演示:
window.qb = {
Utils: {
Analytics: function() {
return { trackEvent: function() { } };
}
}
};
ko.extenders.addFieldTrackingGA = function (target, option) {
target.subscribe(function (newValue) {
if (newValue) {
qb.Utils.Analytics().trackEvent(qb.Utils.Analytics().product,
"form click",
option,
false);
}
});
return target;
};
(function() {
"use strict";
var trackEventFn = function() { };
QUnit.module("Mymodule", {
beforeEach: function() {
window.qb = {
Utils: {
Analytics: function() {
return { trackEvent: trackEventFn };
}
}
};
}
});
QUnit.test("ko.extenders.addFieldTrackingGA", function(assert) {
// arrange
var testObservable = ko.observable(1).extend({
addFieldTrackingGA: "Some button was clicked"
});
// prepare assertion
trackEventFn = function(prod, event, option, somebool) {
assert.ok(true);
// You can also assert on the argument values here
}
assert.expect(1); // Or more than 1, depending on the above
// act
testObservable(5);
});
}());
<link href="https://cdnjs.cloudflare.com/ajax/libs/qunit/1.18.0/qunit.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qunit/1.18.0/qunit.min.js"></script>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
我正在尝试对订阅 ko.observable
的 Knockout JS 扩展程序函数进行单元测试(当值更改时导致它变为 运行)。为了测试它是否正常工作,我需要验证扩展函数在 ko.observable
更改时是否已执行。
这是我目前的测试:
test("ko.extenders.addFieldTrackingGA", function () {
//arrange
var testObservable = ko.observable(1).extend({
addFieldTrackingGA: "Some button was clicked"
});
//act
testObservable(5);
//assert
});
我的问题是:如何断言 ko.extenders.addFieldTrackingGA 在 observable 更改时执行?
这是我要确认执行的代码:
敲除扩展:
ko.extenders.addFieldTrackingGA = function (target, option) {
target.subscribe(function (newValue) {
if (newValue) {
qb.Utils.Analytics().trackEvent(qb.Utils.Analytics().product,
"form click",
option,
false);
}
});
return target;
};
qb.analystics:
/**
* Event = e.g. 'trackEvent'
* Category = e.g. 'error_message_home'
* Action = fieldName
* Label = 'some message'
* ignoreMultiple = false | true | {blank} - if true, gtm actions that are fired more than once will be ignored, defaults to true.
*/
var _pushGTM = function (event, category, action, label, ignoreMultiple) {
if (typeof dataLayer !== 'undefined') { // Add test for dataLayer as breaking Qunit
ignoreMultiple = ignoreMultiple === undefined ? true : ignoreMultiple;
if (_.contains(pushedGTM, action + label) && ignoreMultiple) { // Make sure event doesn't get fired more than once, only fire it the first time
return;
}
var gtmObject = {
'event': event,
'eventDetails.category': category, // Push the value depending on the form (car/house/contents)
'eventDetails.action': action, // Push the form field name.(If there is no field name push "No_field"
'eventDetails.label': label // Please push the exact error string.
}
if (ignoreMultiple) {
pushedGTM.push(action + label);
}
_pushGTMObject(gtmObject);
}
}
您应该意识到您对扩展程序有相当大的依赖性:qb.analytics。目前你(副作用)也在测试,当你只想要测试一个单元:扩展器。
我可以给你至少三个基本选项来处理这个问题:
- 分解出
qb
上的依赖关系,并以某种方式将其注入到您的扩展器中。然后,您的测试可以注入有助于断言的模拟。 - 使用某种 spy/mock 框架,例如 SinonJS。我承认,由于缺乏使用 SinonJS 和类似框架的经验,我不能 100% 确定这种方法是否会奏效。
- 测试中的 Monkey 补丁
qb
以帮助进行断言。
后一种方法有点生硬,但很简单。它的工作原理如下:
(function() {
"use strict";
var trackEventFn = function() { };
QUnit.module("Mymodule", {
beforeEach: function() {
window.qb = {
Utils: {
Analytics: function() {
return { trackEvent: trackEventFn };
}
}
};
}
});
QUnit.test("ko.extenders.addFieldTrackingGA", function(assert) {
// arrange
var testObservable = ko.observable(1).extend({
addFieldTrackingGA: "Some button was clicked"
});
// prepare assertion
trackEventFn = function(prod, event, option, somebool) {
assert.ok(true);
// You can also assert on the argument values here
}
assert.expect(1); // Or more than 1, depending on the above
// act
testObservable(5);
});
}());
这是一个完整的演示:
window.qb = {
Utils: {
Analytics: function() {
return { trackEvent: function() { } };
}
}
};
ko.extenders.addFieldTrackingGA = function (target, option) {
target.subscribe(function (newValue) {
if (newValue) {
qb.Utils.Analytics().trackEvent(qb.Utils.Analytics().product,
"form click",
option,
false);
}
});
return target;
};
(function() {
"use strict";
var trackEventFn = function() { };
QUnit.module("Mymodule", {
beforeEach: function() {
window.qb = {
Utils: {
Analytics: function() {
return { trackEvent: trackEventFn };
}
}
};
}
});
QUnit.test("ko.extenders.addFieldTrackingGA", function(assert) {
// arrange
var testObservable = ko.observable(1).extend({
addFieldTrackingGA: "Some button was clicked"
});
// prepare assertion
trackEventFn = function(prod, event, option, somebool) {
assert.ok(true);
// You can also assert on the argument values here
}
assert.expect(1); // Or more than 1, depending on the above
// act
testObservable(5);
});
}());
<link href="https://cdnjs.cloudflare.com/ajax/libs/qunit/1.18.0/qunit.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qunit/1.18.0/qunit.min.js"></script>
<div id="qunit"></div>
<div id="qunit-fixture"></div>