The latest version of Knockout.js, version 3.2, has a new functionality: the
ability to define and/or load components. Each component is defined with a
viewModel
and a html template
. This means you can make your code even more
modular.
Previously, you would have to manually apply view model bindings to a specific dom element, but this had one big problem: you would have to provide the specific element or somehow be able to identify it each time you would like to apply bindings. An alternative would be to create a custom binding handler or a plugin which would do that for you, but now it's implemented in the very core.
I've been creating a lot of knockout components since the 3.2 release and so far I've been very pleased with the functionality, however in time I noticed I have a big problem.
As it's possible to nest multiple components and define the dependencies either in the view model or directly in the template, I realized that even though I write a lot of unit tests for my viewModels, there was not an easy way to test the interaction between it and it's template. No matter how I tested the view model, I would often have to open the real page to be certain that the binding would be applied successfully, especially if I used two or more components. Just a small typo in the template or viewModel would break everything.
Then I thought of writing my own test module which would make it easier to test these components and let me stop repeating code. Later I extended it to aid me in testing the binding handlers.
It's name is kotest
and it's available on my
GitHub and bower. You can install it via:
bower install kotest
The only dependencies are knockout
and mochajs
. The kotest
library can be
loaded as an AMD module, or as a global object. Mocha should, because of the
way it's written, always be loaded globally.
If your component is already registered, here is an example of the basic usage:
kotest().component('my-component', paramsObj/*, html */)
.test('test description', function(ctx) {
//
// write usual describe() and it() mocha test defs here
//
});
We defined a test case for a component my-component
. The paramsObj
will be
set as it's params binding argument. The third argument is optional, it can be
used to provide a specific html to set the data-bind: component...
to. If you
want to test how your component behaves only on form
elements, you would type
<form></form>
. If this argument is not provided, <div></div>
is used.
Then we called the test()
function. The first argument was the test name, and
the second was a callback. Note that the callback has the ctx
argument. The
ctx
is an object which contains two properties:
- element - the component element
- container - element's parent
It will be set once the it()
's callback is executed. A test DOM element will
be created and attached to the #test
element. This is how the element will
look like:
<div data-bind="component: 'my-component', params: paramsObj"></div>
After that the bindings are applied and tests are executed. Once the test ends, elements are detached, and DOM nodes cleaned.
To see what else you can do with it, visit the project's GitHub page or check the API reference.