我们正试图找出如何将Jest.js
与Knockout.js
一起使用。基本上我们想要创建一个DOM的小片段,例如:
<div class="card" data-bind="component: myCustomComponent"/>
然后能够使用自定义视图模型调用ko.applyBindings()
,并使用该DOM片段和Knockout将组件加载到视图模型中,这样我们就可以进行Jest快照测试。
我们正在努力解决的问题是,如何有效地创建适合ko.applyBindings()
的DOM片段,因为它需要一个我们不确定如何创建的DOM节点/选择
修改
我已经使用了@ user3297291的回答并将以下示例放在一起,遗憾的是我无法开始工作。这是我将自己放在一起的例子:
const jsdom = require("jsdom");
const ko = require("knockout");
describe("Knockout Test", () => {
beforeAll(() => {
ko.components.register("greeting", {
viewModel: function(params) {
//params.name = "test";
//this.message = ko.observable(`Hello ${params.name}`);
this.message = ko.observable("Hello World!");
},
template: '<span data-bind="text: message"/>'
});
});
it("test pass", (done) => {
jsdom.env(`<div class="wrapper"></div>`, [], (err, window) => {
var wrapper = window.document.querySelector(".wrapper");
var element = window.document.createElement("div");
element.setAttribute("data-bind", 'component: "greeting"');
wrapper.appendChild(element);
ko.applyBindings({ name: 'Ian' }, wrapper);
setTimeout(() => {
console.log(element.innerHTML);
expect(element.innerHTML).toMatchSnapshot();
done();
}, 10);
}
);
});
});
如果我将element.setAttribute("data-bind", 'component: "greeting"');
修改为element.setAttribute("data-bind", 'text: name');
,那么它可以正常工作,但加载一个组件(我实际上想要做的事情)似乎总是会导致空element.innerHTML
。
如果你想重现,那么这是一个package.json,我正在运行npm run jest
:
{
"name": "kotest",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"jest": "jest"
},
"author": "",
"license": "ISC",
"dependencies": {
"jasmine": "^2.5.3",
"jest": "^18.1.0",
"jsdom": "^9.9.1",
"knockout": "^3.4.1"
}
}
答案 0 :(得分:1)
在浏览器的javascript环境中,您可以通过代码创建DOM元素来虚拟测试knockout。例如,您可以这样做:
ko.applyBindings({}, document.createElement("div"));
这意味着您可以通过将组件绑定应用于虚拟<div>
并检查其内容来编写任何UI测试。以下示例显示了一些基础知识。
function testComponent(options, test) {
var wrapper = document.createElement("div");
// If you have a HTML string, you can do this by setting
// wrapper.innerHTML = "<div ... ></div>";
var binding = "component: { name: name, params: params }"
wrapper.setAttribute("data-bind", binding);
// Apply bindings to virtual element
ko.applyBindings(options, wrapper);
// Once done, call test with wrapper
setTimeout(test.bind(wrapper));
};
var messageEditorTest = function() {
var opts = { name: "message-editor", params: {} };
testComponent(opts, function() {
var input = this.querySelector("input"),
display = this.querySelector("span"),
vm = ko.dataFor(this.firstElementChild);
console.log("MESSAGE EDITOR TESTS:");
console.log("Has an input field:",
input !== null);
console.log("Has a display field:",
display !== null);
console.log("Length is initially zero:",
display.innerText === "0");
vm.text("Four");
console.log("Length reflects value input:",
display.innerText === "4");
});
};
// Component
ko.components.register('message-editor', {
viewModel: function(params) {
this.text = ko.observable(params && params.initialText || '');
},
template: 'Message: <input data-bind="value: text" /> '
+ '(length: <span data-bind="text: text().length"></span>)'
});
messageEditorTest();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
现在,如果你想在没有浏览器帮助的情况下在Node.js中进行测试,我不确定它是如何工作的......我认为你可以使用像{{ {3}},或者您可以尝试点击jsdom之类的“测试浏览器”。
编辑:我使用jsdom进行了快速测试,一切似乎都运行得很好
npm install jsdom
npm install knockout
创建名为test.js
的文件:
var jsdom = require("jsdom");
var ko = require("knockout");
jsdom.env(
'<div class="wrapper"></div>',
[],
function (err, window) {
var wrapper = window.document.querySelector(".wrapper");
var element = window.document.createElement("div");
element.setAttribute("data-bind", "text: test");
wrapper.appendChild(element);
ko.applyBindings({ test: 'My Test' }, wrapper);
console.log(element.innerHTML); // Logs "My Test"
}
);
node test.js
My Test