I have the following scenario in which I have to check that an URL was build correctly provided some query arguments. I do not expect the system to apply an specific order in the rendered URL, so I came with the following test case which I expected to work:
it('test that url is built correctly', function () {
var args = {
arg1: 'value1',
arg1: 'value2'
};
var rendered_url = render_url(args);
expect(rendered_url).to.equal('/my/url?arg1=value1&arg2=value2')
.or.to.equal('/my/url?arg2=value2&arg1=value1')
;
});
I was pretty surprised to the or
chain to not exists as it makes the statement construction process tidy and cozy.
I know I can workaround this in many ways (for example, using satisfy
), but I wonder:
Mocha is a JavaScript test framework running on Node. js and in the browser. Mocha allows asynchronous testing, test coverage reports, and use of any assertion library. Chai is a BDD / TDD assertion library for NodeJS and the browser that can be delightfully paired with any javascript testing framework.
Chai is an assertion library that is mostly used alongside Mocha. It can be used both as a BDD / TDD assertion library for NodeJS and can be paired with any JavaScript testing framework. It has several interfaces that a developer can choose from and looks much like writing tests in English sentences.
Mocha provides a variety of interfaces for defining test suites, hooks, and individual tests, including TSS, Exports, QUnit, and Require. The default interface is behavior-driven development (BDD), which aims to help developers build software that is predictable, resilient to changes, and not error-prone.
You could use to.include
or .match
:
var chai = require("chai");
var expect = chai.expect;
var option1 = '/my/url?arg1=value1&arg2=value2';
var option2 = '/my/url?arg2=value2&arg1=value1';
var possible = [option1, option2];
var re = /^\/my\/url\?arg1=value1&arg2=value2|\/my\/url\?arg2=value2&arg1=value1$/;
it('1', function () {
var rendered_url = option1;
expect(possible).to.include(rendered_url);
expect(rendered_url).to.match(re);
});
it('2', function () {
var rendered_url = option2;
expect(possible).to.include(rendered_url);
expect(rendered_url).to.match(re);
});
it('3', function () {
var rendered_url = "foo";
expect(possible).to.include(rendered_url);
});
it('4', function () {
var rendered_url = "foo";
expect(rendered_url).to.match(re);
});
The first 2 tests will pass, the last 2 will fail.
I've not done it in this example but both possible
and re
could be generated by a function rather than hand-coding all possible permutations of arguments.
I suspect the reason that .or
is not in Chai is that it would complicate Chai's code quite a bit and make it more cumbersome to use for regular cases. Right now when .equal
is called, it knows it is terminal. If Chai allowed to use .or
, then .equal
could not know right away whether it is terminal or not. Even if you had something like expect(foo).to.equal(bar)
, the call to equal
cannot know that it is terminal. You'd have to do something like what some promises library do to signal that the code is finished with a promise and have a call saying "I'm done here" so it would look like expect(foo).to.equal(bar).end()
. I'm not saying it would be impossible but it would have wide-ranging repercussions.
You could do something like:
expect(rendrered_url).to.satisfy(function(url){
return url === '/my/url?arg1=value1&arg2=value2 || url === '/my/url?arg2=value2&arg1=value1';
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With