Okay as a C# NUnit guy this might be odd.
But does jasmine allow parameterized unit test?
I am not sure if it goes against the "declare" and "it" to make things readable to non programmers.
I have seen some third party plug ins but they are kind of old, not sure if it has been added to jasmine. If I am ment to use a plug in
Just to help anyone who finds this in the future, I have been told on jasmine forum There is no first class support for parameterized tests within Jasmine itself.
Jasmine is a very popular JavaScript behavior-driven development (In BDD, you write tests before writing actual code) framework for unit testing JavaScript applications. It provides utilities that can be used to run automated tests for both synchronous and asynchronous code.
Jest has a built-in support for tests parameterized with data table that can be provided either by an array of arrays or as tagged template literal.
Based on piotrek's answer and the article Parameterized testing in Javascript, you could also use the following approach which uses ES6 syntax:
[ ['abc', 3], ['ab', 2], ['', 0], ].forEach(([string, expectedLength]) => { it(`should return length ${expectedLength} for string "${string}"`, () => { expect(string.length).toBe(expectedLength); }); });
I have tested it with the Jest test framework, but it should work with Jasmine as well.
Another solution is to use Array of Objects instead of Array of Arrays. It fits better if you use some typing system like TypeScript.
Imagine you have the following parametrised test:
it('action(value) should reset the forms pool only if value is true', () => { [ [true, 1], [false, 0], ].forEach(([value, calledTimes]) => { spyResetFormsPool.calls.reset(); component.action(value); // type error #1 expect(spyResetFormsPool).toHaveBeenCalledTimes(calledTimes); // type error #2 }); });
with TypeScript, it will fail to compile giving two errors:
error #1:
error TS2345: Argument of type 'number | boolean' is not assignable to parameter of type 'boolean'.
error #2:
error TS2345: Argument of type 'number | boolean' is not assignable to parameter of type 'number'. Type 'true' is not assignable to type 'number'.
That is because TypeScript sees an array of 'number | boolean'.
We could quickly solve this warning by using some explicit cast:
it('action(value) should reset the forms pool only if value is true', () => { [ [true, 1], [false, 0], ].forEach(([value, calledTimes]) => { spyResetFormsPool.calls.reset(); component.action(value as boolean); // necessary cast expect(spyResetFormsPool).toHaveBeenCalledTimes(calledTimes as number); // necessary cast }); });
however this solution is not very nice.
A better way is to use Array of Objects, so the types are correctly handled by default and there is no need of explicit casting:
it('action(value) should reset the forms pool only if value is true', () => { [ { value: true, calledTimes: 1 }, { value: false, calledTimes: 0 }, ].forEach(({ value, calledTimes }) => { spyResetFormsPool.calls.reset(); component.action(value); expect(spyResetFormsPool).toHaveBeenCalledTimes(calledTimes); }); });
Do you want to use for
instead of forEach
(I personally find it more readable)? That's also possible:
it('action(value) should reset the forms pool only if value is true', () => { for (const {value, calledTimes} of [ {value: true, calledTimes: 1}, {value: false, calledTimes: 0}, ]) { spyResetFormsPool.calls.reset(); component.action(value); expect(spyResetFormsPool).toHaveBeenCalledTimes(calledTimes); } });
Alternatively, you can also move the it
inside the loop. When I do this, I usually add a testId
to each object so I can keep track of which tests are failing:
for (const {value, calledTimes} of [ { testId: 1, value: true, calledTimes: 1 }, { testId: 2, value: false, calledTimes: 0 }, ]) { it(`action(value) should reset the forms pool only if value is true [${testId}]`, () => { spyResetFormsPool.calls.reset(); component.action(value); expect(spyResetFormsPool).toHaveBeenCalledTimes(calledTimes); }); }
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