I have a lot of tests which are virtually the same. In the interests of DRY and scanability I'd like to abstract the tests into a single function and then call that function with a few parameters. The function would then call it
and add the spec to the suite.
It seems to work, except the specs don't get run in the same way as the other specs and beforeEach
is not called before the specs defined in the common function.
define(['modules/MyModule','jasmine/jasmine'], function(MyModule) {
describe('myModule', function() {
function commonTests(params) {
it('should pass this test OK', function() {
expect(true).toBe(true);
});
it('should fail because module is undefined', function() {
expect(module[params.method]()).toBe('whatever');
});
}
var module;
beforeEach(function() {
module = new MyModule();
});
describe('#function1', function() {
commonTests({
method: 'function1'
});
});
describe('#function2', function() {
commonTests({
method: 'function2'
});
});
});
});
Is there any way of doing this and maintaining the functionality of beforeEach
and afterEach
?
UPDATE:
Looks like I got my example wrong, sorry. Here's the case that fails:
define(['modules/MyModule'], function(MyModule) {
function commonTests(params) {
it('will fail because params.module is undefined', function() {
expect(typeof params.module).toBe('object');
expect(typeof params.module[params.method]).toBe('function');
});
it('has a few tests in here', function() {
expect(true).toBe(true);
});
}
describe('MyModule', function() {
var module;
beforeEach(function() {
module = new MyModule();
});
describe('#function1', function() {
commonTests({
module: module,
method: 'function1'
});
});
describe('#function2', function() {
commonTests({
module: module,
method: 'function2'
});
});
});
});
I think it fails because the value of module
is preserved as part of the call to commonTests
instead of always using the current value of module
as in the first example. I'll post my solution when I get there...
Thanks to Andreas for pointing out that my first example actually worked! The final solution I'm using is very similar:
define(['modules/MyModule'], function(MyModule) {
var module;
function commonTests(params) {
it('will not fail because module is shared', function() {
expect(typeof module).toBe('object');
expect(typeof module[params.method]).toBe('function');
});
it('has a few tests in here', function() {
expect(true).toBe(true);
});
}
describe('MyModule', function() {
beforeEach(function() {
module = new MyModule();
});
describe('#function1', function() {
commonTests({
method: 'function1'
});
});
describe('#function2', function() {
commonTests({
method: 'function2'
});
});
});
});
Although if you needed to have the ability to pass in module
as an argument to commonTests
you would have to take a slightly different approach and have a different function for each it
block:
define(['modules/MyModule'], function(MyModule) {
var module;
function commonTest1(params) {
expect(typeof module).toBe('object');
expect(typeof module[params.method]).toBe('function');
}
function commonTest2(params) {
expect(true).toBe(true);
}
describe('MyModule', function() {
beforeEach(function() {
module = new MyModule();
});
describe('#function1', function() {
it('will not fail because module is shared', function() {
commonTest1({ method: 'function1' });
});
it('has a few tests in here', function() {
commonTest2({ method: 'function1' });
});
});
describe('#function2', function() {
it('will not fail because module is shared', function() {
commonTest1({ method: 'function2' });
});
it('has a few tests in here', function() {
commonTest2({ method: 'function2' });
});
});
});
});
This way the executions of the functions containing the common tests is delayed until after beforeEach has run its callback.
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