I'm trying to figure out where to put a function to delete database and close connection after all tests have run.
Here are my nested tests:
//db.connection.db.dropDatabase();
//db.connection.close();
describe('User', function(){
beforeEach(function(done){
});
after(function(done){
});
describe('#save()', function(){
beforeEach(function(done){
});
it('should have username property', function(done){
user.save(function(err, user){
done();
});
});
// now try a negative test
it('should not save if username is not present', function(done){
user.save(function(err, user){
done();
});
});
});
describe('#find()', function(){
beforeEach(function(done){
user.save(function(err, user){
done();
});
});
it('should find user by email', function(done){
User.findOne({email: fakeUser.email}, function(err, user){
done();
});
});
it('should find user by username', function(done){
User.findOne({username: fakeUser.username}, function(err, user){
done();
});
});
});
});
Nothing seems to work. I get Error: timeout of 2000ms exceeded
You can define a "root" after() hook before the 1st describe() to handle cleanup:
after(function (done) {
db.connection.db.dropDatabase(function () {
db.connection.close(function () {
done();
});
});
});
describe('User', ...);
Though, the error you're getting may be from the 3 asynchronous hooks that aren't informing Mocha to continue. These need to either call done() or skip the argument so they can be treated as synchronous:
describe('User', function(){
beforeEach(function(done){ // arg = asynchronous
done();
});
after(function(done){
done()
});
describe('#save()', function(){
beforeEach(function(){ // no arg = synchronous
});
// ...
});
});
From the docs:
By adding a callback (usually named done) to it() Mocha will know that it should wait for completion.
I implemented it a bit different.
I removed all documents in the "before" hook - found it a lot faster than dropDatabase().
I used Promise.all() to make sure all documents were removed before exiting the hook.
beforeEach(function (done) {
function clearDB() {
var promises = [
Model1.remove().exec(),
Model2.remove().exec(),
Model3.remove().exec()
];
Promise.all(promises)
.then(function () {
done();
})
}
if (mongoose.connection.readyState === 0) {
mongoose.connect(config.dbUrl, function (err) {
if (err) {
throw err;
}
return clearDB();
});
} else {
return clearDB();
}
});
Related
For example something like this
func do something()
{
api.ajax('') //Ajax call that triggers inside the function
.done(response){
do something with response
}
}
How do I get to expect something from the response and make my assertions? ANy help would be really helpful! Thanks in advance!
Using jasmine-ajax in tests looks like this:
describe('Sample test', function(){
var request = function(arg){
return new Promise(function(resolve, reject){
$.ajax({
method:'GET',
url: 'example.com/api/'+arg,
success: function(response){
resolve(changeResponse(response));
},
error: reject
});
});
function changeResponse(response){
return response.key + '-changed';
}
};
var TestResponses = {
someEndPoint: {
success: {
status: 200,
responseText: '{"key":"value"}'
}
}
};
beforeEach(function(){
jasmine.Ajax.install();
});
afterEach(function(){
jasmine.Ajax.uninstall();
});
it('can be called with for some end-point', function(){
spyOn($, 'ajax');
request('something');
expect($.ajax).toHaveBeenCalled();
var actualAjaxOptions = $.ajax.calls.mostRecent().args[0];
expect(actualAjaxOptions).toEqual(jasmine.objectContaining({
method:'GET',
url: 'example.com/api/something',
}));
});
it('modifies response as expected', function(done){
request('something').then(function(){
expect(arguments[0]).toEqual('value-changed');
done();
}, function(reason){
done.fail();
});
jasmine.Ajax.requests.mostRecent().respondWith(TestResponses.someEndPoint.success);
});
})
Pleas note that:
jasmine-ajax is currently compatible with any library that uses
XMLHttpRequest. Tested with jQuery and Zepto.
(from docs)
I've a controller with an action that invoke a method that do some async stuff and return a promise.
export default Ember.Controller.extend({
_upload: function() {
// return a promise
},
actions: {
save: function(item) {
this._upload(item).then(function(response) {
// Handle success
}, function(error) {
// Handle error
}
}
}
});
I would like to unit test the code under Handle success and Handle error.
In my unit test I've mocked the _uploadMethod using
controller.set("_upload", function() {
return new Ember.RSVP.Promise(function(resolve) {
resolve({name: "image1"});
});
});
And then I invoke the action and assert that the success handler has done is job
controller.send("save", "item");
assert.equal(controller.get("selected.item"), "item");
The problem is that the assertion fails because it's run before the promise is resolved and all the stuff in success handler is completed.
How can I wait the promise to resolve before the assertion is checked?
What if you try this instead:
controller.set("_upload", function() {
const promise = new Ember.RSVP.Promise(function(resolve) {
resolve({name: "image1"});
});
promise.then(() => Ember.run.next(() => {
assert.equal(controller.get("selected.item"), "item");
}));
return promise;
});
controller.send("save", "item");
A bit hacky way, but it might work.
To test async methods, you can use the test helper waitUntil to wait for the expected return of the method, like the code below.
controller.send('changeStepAsyncActionExample');
await waitUntil(() => {
return 'what you expect to the Promise resolve';
}, { timeout: 4000, timeoutMessage: 'Your timeout message' });
// If not timeout, the helper below will be executed
assert.ok(true, 'The promise was executed correctly');
I am trying to write a test for an action handler on one of my components. I am stubbing out the save method on one of my models to return a resolved promise using Em.RSVP.Promise.resolve()
in my component, i chain on that promise using then:
return target
.save()
.then(function(){
selected.rollback();
this.sendAction('quicklinkChanged', target);
}.bind(this),this.notify_user_of_persistence_error.bind(this, 'Save As'));
this is a pattern that i use a lot server-side where we use when for our promise library. however, when i do this client-side, i never end up inside the function in the then block so i cannot assert any of the functionality there in my unit tests.
can anyone provide any insight on the best way to do this?
We moved our callbacks out of the method so we could call them separately and verify functionality, or replace them and verify they were called.
Controller Example:
App.IndexController = Em.Controller.extend({
randomProperty: 1,
async: function(fail){
return new Em.RSVP.Promise(function(resolve, reject){
if(fail){
reject('fdas');
}else{
resolve('foo');
}
});
},
doAsyncThing: function(fail){
return this.async(fail).then(this.success.bind(this), this.failure.bind(this));
},
success: function(){
this.set('randomProperty', 2);
},
failure: function(){
this.set('randomProperty', -2);
}
});
Tests
test("async success", function(){
var ic = App.IndexController.createWithMixins();
stop();
ic.doAsyncThing(false).then(function(){
start();
equal(ic.get('randomProperty'), 2);
});
});
test("async fail", function(){
var ic = App.IndexController.createWithMixins();
stop();
ic.doAsyncThing(true).then(function(){
start();
equal(ic.get('randomProperty'), -2);
});
});
test("async success is called", function(){
expect(1);
var ic = App.IndexController.createWithMixins();
ic.success = function(){
ok(true);
};
stop();
ic.doAsyncThing(false).then(function(){
start();
});
});
test("async failure is called", function(){
expect(1);
var ic = App.IndexController.createWithMixins();
ic.failure = function(){
ok(true);
};
stop();
ic.doAsyncThing(true).then(function(){
start();
});
});
test("doAsyncThing returns a promise", function(){
expect(1);
var ic = App.IndexController.createWithMixins();
ok(ic.doAsyncThing(true).then);
});
Example: http://emberjs.jsbin.com/wipo/37/edit
I have the following jasmine test:
it('should resolve promise', inject(function ($q, $rootScope) {
function getPromise(){
var deferred = $q.defer();
setTimeout(function(){
deferred.resolve(true);
}, 1000);
return deferred.promise;
}
var p = getPromise();
var cb = jasmine.createSpy();
runs(function(){
expect(cb).not.toHaveBeenCalled();
p.then(cb);
$rootScope.$apply();
});
waitsFor(function(){
return cb.callCount == 1;
});
runs(function(){
expect(cb).toHaveBeenCalled();
$rootScope.$apply();
});
}));
I thought $rootScope.$apply was supposed to resolve all outstanding promises, but somehow it does not happen in this test.
How do i trigger promise resolving in a test like this? please help!
I think the $rootScope.$apply() is being called too soon in your case. This should work:
function getPromise(){
var deferred = $q.defer();
setTimeout(function(){
deferred.resolve(true);
$rootScope.$apply();
}, 1000);
return deferred.promise;
}
Update
You can inject mock $timeout service and resolve the promise in that explicitly using $timeout.flush().
it('should resolve promise', inject(function ($q, $timeout, $rootScope) {
function getPromise(){
var deferred = $q.defer();
$timeout(function(){
deferred.resolve(true);
}, 1000);
return deferred.promise;
}
// ...
$timeout.flush();
// ...
I am using jasmine runner to test angular code.
describe('des1', function() {
var des1Var = function(){};
beforeEach() {
//....
}
describe('test1', function() {
var scope4Compile = $rootScope.$new();
var des2Var = des1Var(scope4Compile); // returns undefined.
beforeEach(function() {
des2Var = des1Var(scope4Compile); // returns des1Var() fine;
})
it('should do ', function(){
//should do...
})
it('should also do', function(){
//should also do...
})
})
})
I need to instantiate something once before the it statements, if run multiple times result is pretty bad. How can I get it done properly?
I believe it you call it once in the first beforeEach it will be run one time for each describe that is below it.
In the code below, des2Var will be set once for the whole test1 describe.
describe('des1', function() {
var des1Var = function () { };
beforeEach(function () {
var des2Var = des1Var();
});
describe('test1', function() {
it('should do ', function(){
//should do...
});
it('should also do', function(){
//should also do...
});
});
});