我正在尝试对一个订阅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
});
我的问题是:当observable被更改时,如何断言ko.extenders.addFieldTrackingGA被执行了?
以下是我要确认执行的代码:
Knockoutextension:
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);
}
}
答案 0 :(得分:0)
你应该意识到你在扩展器中有很重的依赖性:qb.analytics。目前,您(通过副作用)还在测试时,只需要想要来测试一个单元:扩展程序。
我可以给你至少三个基本选项来处理这个问题:
qb
的拒绝因素排除在外,并以某种方式将其注入您的扩展程序。然后,您的测试可以注入有助于断言的模拟。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>
&#13;