Is it possible to define the Jasmine specification inside a function and still have everything applied before it?

I have many tests that are almost the same. In the interest of DRY and the possibility of scanning, I would like to abstract tests for one function, and then call this function with several parameters. Then the function will call it and add the specification to the package.

This seems to work, except that the specifications do not start like other specifications, and beforeEach not called before the specifications defined in the general 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 a way to do this and maintain the functionality of beforeEach and afterEach ?

UPDATE:

It looks like I got my example wrong, sorry. Here is a 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 module value is saved as part of the commonTests call commonTests instead of always using the current module value, as in the first example. I will send my decision when I get ...

+6
source share
2 answers

Thanks to Andreas for pointing out that my first example will really work! 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 need to be able to pass module as an argument to commonTests , you will have to take a slightly different approach and have different functions 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' }); }); }); }); }); 

Thus, the execution of functions containing common tests is delayed until beforeEach performs a callback.

+4
source

Yes, this script is great for us. We use chutzpah to run tests in our private checks, and our tests will fail without afterEach functions.

But the define line looks like require.js . We had a few problems with this ... I believe that MyModule is undefined or not defined as expected. Have you tried to set a breakpoint in the beforeEach method to find out if it was called and what is the value of MyModule ? What do you call tests?

When I run your code without the define line, the beforeEach function beforeEach called 4x - as expected. Btw I used chutzpah.console.exe to call the tests.

Edit:

Yes, now I can reproduce the problem on my PC. And it is much clearer for me. At the beginning of module there is undefined, since each variable is undefined. Then you register your functions in jasmine with beforeEach and describe . Jasmine begins with an assessment

 function() { commonTests({ module: module, method: 'function1' }); } 

which was passed to the first describe . On the module: module JS copies the var module reference into the property of the new module objects, and this points to undefined . When calling the beforeEach it changes the var module reference to the correct value, but the invalid link is already copied ...

I tried to move the var module above the function commonTests and used this variable in the tests instead of params.module , and they passed as expected. I don't know if this is an option in your environment, but I hope this helps.

Congratulated Andreas

0
source

All Articles