How to test Jasmine setup code? - javascript

Update: I figured out what the issue was, see my comment below.
Is there a way to guarantee state before each Jasmine test?
For example:
describe('some thing', function () {
beforeEach(function () {
doSetup();
// this expect does not evaluate :(
expect(something).toBe(inSomeState);
});
it('has some behavior', function () {
// test code
});
});
The expect inside of the setup make no difference at all. Even throwing an error in the beforeEach does nothing. I would like to have some assurance that the setup has completed correctly before running the next test.. is there a way to do this?

Okay I see what the issue is. Hoping this will help other people out there having this same issue. grunt-contrib-jasmine does not display errors or failed expects inside of beforeEach or afterEach with the display option set to short. Setting this option to full will once again display Errors and failed expects.

Related

SinonJS Spy Cannot Restore Read Only Method/Property of Object

It gives me TypeError: Cannot assign to read only property 'get' of object '#<Config>'.
I'm using mocha 8.0.1, chai 4.2.0, sinon 9.0.2 for Unit Testing.
I'm spying on a method in the config npm package.
Here's how I spy the get method:
...
before(() => {
sandbox = sinon.createSandbox();
configStub = sandbox.spy(config, 'get');
});
after(() => {
sandbox.restore();
});
it('should something', async () => {
console.log('Just logging');
config.get('LOG.LEVEL'); // just to show the point. if I remove this line, it doesn't throw the error
});
...
What happens is, if I run config's get method somewhere during the test, it can not be restored by spy. It throws that read-only property error. But when the config.get function is never called, it doesn't throw that error (I don't understand why not). For stub there's no problem, it can restore just fine.
But the reason I'm using spy is because I want config.get to work like it normally does while I'm testing my module/function that's using it, I just want to spy on it. And I also need to be able to restore it after this test suite. I spy on it because I need to test that it's being called by my module/function with some specific parameters.
How do I spy on a read-only property/method, allow my module/function to use it like it normally does, and then restore it?
Thank you :)
You can set ALLOW_CONFIG_MUTATIONS environment variable to true for the test run.
In this way config.get invocation will not freeze the config which should resolve the issue.
You can find the env var description in the documentation:
https://github.com/lorenwest/node-config/wiki/Environment-Variables#allow_config_mutations

Stop after failed QUnit.js test

Is there a way to get QUnit.js to not run the remaining tests after a single one fails?
Using the following code as an example:
QUnit.test('test1', function(assert) {
assert.equal(1,1);
assert.equal(1,2);
assert.equal(3,3);
});
QUnit.test('test2', function(assert) {
assert.equal(4,4);
assert.equal(5,5);
assert.equal(6,6);
});
Is there some way to get QUnit to stop executing after the assert.equal(1,2)? This means that test2 should never be run.
The best way to stop QUnit after test case fail will be
QUnit.testDone( function( details ) {
if (details.failed>0){
QUnit.config.queue.length = 0;
}
});
Okay, based on my comments above I ran the code below and things to stop as I think you want them to. Again, as I said in the comments, I would really investigate whether this is a good idea. Generally you want your tests to be idempotent such that any one failure does not affect any other test.
Note that we have to set the reorder config option to false here, otherwise QUnit will attempt to run the previously failed test first to "short circuit" things, but you don't want that I'm guessing. I also added a "test0" just to see the fill effect.
QUnit.config.reorder = false;
// This is how we detect the failure and cancel the rest of the tests...
QUnit.testDone(function(details) {
console.log(details);
if (details.name === 'test1' && details.failed) {
throw new Error('Cannot proceed because of failure in test1!');
}
});
QUnit.test('test0', function(assert) {
assert.equal(1,1);
assert.equal(2,2);
assert.equal(3,3);
});
QUnit.test('test1', function(assert) {
assert.equal(1,1);
assert.equal(1,2);
assert.equal(3,3);
});
QUnit.test('test2', function(assert) {
assert.equal(4,4);
assert.equal(5,5);
assert.equal(6,6);
});
You won't get any visual feedback that the tests were canceled because this isn't really interacting with the QUnit UI. However, because we threw an Error object you can open the developer console and see the output there:

How to intercept error when expect fails? Jasmine and frisby

I am creating HTTP tests with frisby.js which works on top of jasmine.js.
I also have to create some mongoDB objects to test against.
The problem is when I want to clean up these DB objects. When one of the expects fail I want to intercept that and call my own cleanup function. This means that after each failed test, I won't be able to remove the test objects from the DB.
The afterEach function in jasmine does not work properly and jasmine does not have any support for afterAll or beforeAll yet.
That is why I have made the tests as they are today.
it("testing userform get with correct userID and expect correct return", function() {
var innerUserId = userID;
frisby.create('Should retrieve correct userform and return 200 when using a valid userID')
.get(url.urlify('/api/userform', {id: innerUserId}))
.expectStatus(200)
.afterJSON(function(userform){
// If any of these fail, the after function wont run.
// I want to intercept the error so that I can make sure that the cleanUp function is called
// afterEach does not work. I have tried with done()
var useridJSON = userform.UserId.valueOf();
var firstnameJSON = userform.firstname.valueOf();
var surnameJSON = userform.surname.valueOf();
expect(firstnameJSON).toMatch(testUser.firstName);
expect(surnameJSON).toMatch(testUser.surname);
expect(useridJSON).toMatch(innerUserId);
})
.after(function(){
cleanUp(innerUserId);
})
.toss();
});
I am wondering if there is a way to intercept the error for "expect" in frisby or jasmine so that I can make a call to my own cleanup function before exiting.
Full example here
The quickest solution to this problem is to wrap the error code in a try-catch.
This is because if a javascript error occurs, jasmine will NOT keep running assertions. This is different from an assertion error. If an assertion error occurs, jasmine and frisby will keep on testing all the other assertions and then do the "after"-function.
.afterJSON(function(userform){
try {
var useridJSON = userform.UserId.valueOf();
var firstnameJSON = userform.firstname.valueOf();
var surnameJSON = userform.surname.valueOf();
catch(e) {
cleanUp(innerUserId);
// Can do a throw(e.message); here aswell
}
expect(firstnameJSON).toMatch(testUser.firstName);
expect(surnameJSON).toMatch(testUser.surname);
expect(useridJSON).toMatch(innerUserId);
})
This is not the pretty way, but works.
I ended up adding the throw(e) and placed the expects in a finally scope. This way I got jasmine to present all the errors that occured in the test.
As for "before exiting", how about this:
process.on('uncaughtException', function(err) {
console.error(' Caught exception: ' + err);
});

How can I make this test pass in Jasmine?

I have a Jasmine unit test and in it I have this 'expect'...
expect(mockService.create).toHaveBeenCalledWith(new ToDoItem('a#b.com', 'get milk'));
In my controller I have the following...
todoService.create($scope.newToDo,
function() {
}, function() {
});
But I always get an error because of the final two functions that I pass the service for success and failure. How can I stop this from happening? How do I add them to the expect clause?
Thanks
You may be able to use jasmine.any(Function), or jasmine.objectContaining.
Fair warning, I've never done this myself. However, from the documentation, at least one of them should provide the behaviour you want.

Ember.js with Ember.testing = true

I am trying to get testing working in Ember.js with the Ember.testing = true flag set to disable the automatic run loop etc
I have this code
Ember.testing = true;
Ember.run(function() {
App = Ember.Application.create();
});
App.Router.map(function() {
this.route("home", { path: "/" });
});
Ember.run(function() {
App.initialize();
});
And i get thuis error already
Uncaught Error: assertion failed: You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in an Ember.run
I know you need to run async code within a Ember.run which i have as per any examples i can find!!
Can anyone show me what i am doing wrong or even get the jsin example to not show this error ?
See jsbin here http://jsbin.com/uxalap/14/edit
UPDATED:
I am using Konacha to run my tests and when i use the latest RC1 i get an error when wrapping the Ember.Application.create() and App.initialize() in Em.run. When i remove these i get no errors. Is this correct now in latest master ?
Thanks
Rick
Ember.testing was changed since RC1, if you want to use it you should use master
Here's an updated working JSBin

Categories

Resources