Checking should have a controller defined - node.js

I am checking whether in my module PracticeCtrl exists. I written following test for this.
Gives me error : ReferenceError: myApp is not defined
describe('myApp', function() {
describe('Controller: PracticeCtrl', function () {
// load the controller's module
beforeEach(function () {
// Load the controller's module
module('myApp');
});
it('should have a PracticeCtrl controller', function() {
expect(myApp.PracticeCtrl).toBeDefined();
});
});
});
How to check in my module a controller exists? As i am new for this, have less knowledge on syntax.

describe("SomeControllerTest", function () {
var scope, ctrl;
beforeEach(module('myApp'));
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new();
ctrl = $controller('SomeController', {
$scope: scope
});
}));
it("should be defined", function () {
expect(ctrl).toBeDefined();
});
});

Related

How to reuse an element inside of a function in protractor page object model?

I am using protractor with Jasmine in windows 10 OS. This is my page for stack over flow login .May I know how to access txt_username inside of clearme: function().
pgstackover.js
//pgstackover.js
'use strict';
module.exports = {
txt_username: element(by.id('email')),
txt_password: element(by.id('password')),
btn_submit: element(by.id('submit-button')),
clearme: function() {
txt_username.isDisplayed();
txt_username.clear();
txt_password.clear()
} ,
go: function() {
browser.driver.ignoreSynchronization = true;
browser.waitForAngularEnabled(false);
browser.driver.manage().window().maximize();
browser.driver.get('https://stackoverflow.com/users/login'); //overrides baseURL
}
This is my spec.js file and it works until clear me function and fails with error Failed: txt_username is not defined
var toDoPage = require('../../../../pages/pgstackover.js');
describe('My first non angular class', function() {
it('should navigate to stack overflow login page', function() {
toDoPage.go();
});
it ('My function', function() {
// browser.driver.get('https://stackoverflow.com/users/login');
toDoPage.txt_username.sendKeys('6');
toDoPage.txt_password.sendKeys('winchester');
var value=toDoPage.btn_submit.getText();
expect(value).toEqual("Log in");
});
it('clear me', function() {
toDoPage.clearme();
});
})
Too make long story short your code does not know what is txt_username so you need to point it out. You are missing .this in your clearme function.
I haven't used a promise manager for ages (since it is obsolete) so here is a working example using async/await:
async clearme() {
await this.txt_username.isDisplayed();
await this.txt_username.clear();
await this.txt_password.clear();
}

jest mocking functions without passing as a callback

I have some code like:
module.exports = {
idCheck: function(errors) {
errors.some( (error) => {
if (error.parentSchema.regexp === '/^((?!\\bMyId\\b).)*$/i') {
this._recordError('IDCHECK');
}
});
}
};
I am trying to test it using jest with this:
const IDCheck = require(
'./IDCheck'
);
let errors = [
{
parentSchema: {
regexp: '/^((?!\\bMyId\\b).)*$/i'
}
}
];
describe('IDCheck', () => {
afterEach(() => {
jest.restoreAllMocks();
});
it('calls _recordError with IDCHECK', () => {
jest.spyOn(this, '_recordError');
IDCheck.idCheck(errors);
});
});
however, when running jest, I get
Cannot spy the _recordError property because it is not a function; undefined given instead
Is there a way of mocking, testing for _recordError() having been called, or not called and with the correct parameter, without passing _recordError through as a parameter?
A few things about this line: jest.spyOn(this, '_recordError');
this has to be IDCheck because there is no this in scope since you are using arrow functions that inherit this if previously set (which it isn't). You can console.log(this) right above the line to prove that point.
'_recordError' is not a method of IDCheck. spyOn checks the target's methods, not methods called within it. Now if _recordError is a method of IDCheck, then you should be ok.
Finally, you basically have to return the data you want in order to verify it. There's no real way to check what was passed unless you return it.
Here's a solution I came up with that does not include some fixes you'd have to implement to fix the potential workflow flaws.
const IDCheck = {
idCheck: function(errors) {
return errors.map(error => {
if (error.parentSchema.regexp === '/^((?!\\bMyId\\b).)*$/i') {
return this._recordError('IDCHECK')
}
})
},
_recordError: function(data) {
return data
}
}
let errors = [
{
parentSchema: {
regexp: '/^((?!\\bMyId\\b).)*$/i'
}
}
];
describe('IDCheck', () => {
afterEach(() => {
jest.restoreAllMocks();
});
it('calls _recordError with IDCHECK', () => {
const spy = jest.spyOn(IDCheck, '_recordError')
const check = IDCheck.idCheck(errors).includes('IDCHECK')
expect(spy).toHaveBeenCalled()
expect(check).toBe(true)
});
});

Testing method signatures in Node.js

I'm relatively new to Unit-testing and TDD specificly and am about to start my first project with TDD using mocha and chai.
Am I supposed to test the existence and parameter length of the methods?
And if so, is there any better way of doing it than I currently am? It feels extremly verbose, especially when repeating this for most of my classes.
For understand I've set up some dummy test.
test/index.js
'use strict';
const assert = require('chai').assert;
const Test = require('../lib/index.js');
describe('Test', function() {
it('should be a function without parameters', function() {
assert.isFunction(Test);
assert.lengthOf(Test, 0);
});
let test;
beforeEach(function() {
test = new Test();
});
describe('static#method1', function() {
it('should have static method method1 with 1 parameter', function() {
assert.property(Test, 'method1');
assert.isFunction(Test.method1);
assert.lengthOf(Test.method1, 1);
});
it('should assert on non-string parameters', function() {
const params = [
123,
{},
[],
function() {}
];
params.forEach(function(param) {
assert.throws(function() {
Test.method1(param)
});
});
});
it('should return "some value"', function() {
assert.equal(Test.method1('param'), 'some value')
});
});
describe('method2', function() {
it('should have method method2 with 2 parameters', function() {
assert.property(test, 'method2');
assert.isFunction(test.method2);
assert.lengthOf(test.method2, 2);
});
it('should assert on non-number parameters', function() {
const params = [
'some string',
{},
[],
function() {}
];
params.forEach(function(param) {
assert.throws(function() {
test.method2(param)
});
});
});
it('should add the parameters', function() {
assert.equal(test.method2(1, 2), 3);
assert.equal(test.method2(9, -2), 7);
assert.equal(test.method2(3, -12), -9);
assert.equal(test.method2(-7, -5), -12);
})
});
});
And the tested implementation.
lib/index.js
'use strict';
const assert = require('chai').assert;
exports = module.exports = (function() {
class Test {
static method1(param0) {
assert.typeOf(param0, 'string');
return 'some value';
}
method2(param0, param1) {
assert.typeOf(param0, 'number');
assert.typeOf(param1, 'number');
return param0 + param1;
}
}
return Test;
}());
No, such detailed tests are not necessary. What is the value of them? What do they help you to achieve?
Usually when testing functions we test behavior of a function, not its implementation. Implementation can completely change without changing the observable behavior: for example, you can find more readable way to rewrite your code or a more performant algorithm.
You test the call signature of your function by the whole set of tests for it, indirectly. Every test provides an example of how to use your function, thus ensuring its call signature and return parameters.

How can I stub a Promise such that my test can be run synchronously?

I am trying to unit test a module by stubbing one of its dependencies, in this case the UserManager
A simplified version of the module is as follows:
// CodeHandler
module.exports = function(UserManager) {
return {
oAuthCallback: function(req, res) {
var incomingCode = req.query.code;
var clientKey = req.query.key;
UserManager.saveCode(clientKey, incomingCode)
.then(function(){
res.redirect('https://test.tes');
}).catch(function(err){
res.redirect('back');
}
);
}
};
};
I'm stubbing the UserManager's saveCode function which returns a Promise such that it returns a resolved Promise, but when I assert that res.redirect has been called, alas at the time of the assertion res.redirect has not yet been called.
A simplified version of the unit test is:
// test
describe('CodeHandler', function() {
var req = {
query: {
code: 'test-code',
key: 'test-state'
}
};
var res = {
redirect: function() {}
};
var expectedUrl = 'https://test.tes';
var ch;
beforeEach(function() {
sinon.stub(UserManager, 'saveCode').returns(
new RSVP.Promise(function(resolve, reject){
resolve();
})
);
sinon.stub(res, 'redirect');
ch = CodeHandler(UserManager);
});
afterEach(function() {
UserManager.saveCode.restore();
res.redirect.restore();
});
it('redirects to the expected URL', function(){
ch.oAuthCallback(req, res);
assert(res.redirect.calledWith(expectedUrl));
})
});
How can I properly stub the promise such that the method under test behaves synchronously?
I've worked out a solution using sinon-stub-promise.
describe('CodeHandler', function() {
var req = {
query: {
code: 'test-code',
key: 'test-state'
}
};
var ch;
var promise;
var res = {
redirect: function() {}
};
beforeEach(function() {
promise = sinon.stub(UserManager, 'saveCode').returnsPromise();
ch = CodeHandler(UserManager);
sinon.stub(res, 'redirect');
});
afterEach(function() {
UserManager.saveCode.restore();
res.redirect.restore();
});
describe('can save code', function() {
var expectedUrl = 'https://test.tes';
beforeEach(function() {
promise.resolves();
});
it('redirects to the expected URL', function(){
ch.oAuthCallback(req, res);
assert(res.redirect.calledWith(expectedUrl));
});
});
describe('can not save code', function() {
var expectedUrl = 'back';
beforeEach(function() {
promise.rejects();
});
it('redirects to the expected URL', function(){
ch.oAuthCallback(req, res);
assert(res.redirect.calledWith(expectedUrl));
})
})
});
This works perfectly.
Well, the easiest thing would be not to stub it to run synchronously at all since that might change execution order and use Mocha's built in promises support (or jasmine-as-promised if using jasmine).
The reason is there can be cases like:
somePromise.then(function(){
doB();
});
doA();
If you cause promises to resolve synchronously the execution order - and thus output of the program changes, making the test worthless.
On the contrary, you can use the test syntax:
describe("the test", () => { // use arrow functions, node has them and they're short
it("does something", () => {
return methodThatReturnsPromise().then(x => {
// assert things about x, throws will be rejections here
// which will cause a test failure, so can use `assert`
});
});
});
You can use the even lighter arrow syntax for single lines which makes the test even less verbose:
describe("the test", () => { // use arrow functions, node has them and they're short
it("does something", () =>
methodThatReturnsPromise().then(x => {
// assert things about x, throws will be rejections here
// which will cause a test failure, so can use `assert`
});
);
});
In RSVP, you can't set the scheduler as far as I know so it's quite impossible to test things synchronously anyway, other libraries like bluebird let you do it at your own risk, but even in libraries that let you do it it's probably not the best idea.

How to test stubbed database queries

I have a Sails.Js controller that looks like this
module.exports = {
confirmID: function(req,res) {
var uid = req.params.id;
User.findOne({id:uid}).exec(function(err,user) {
// ...
});
}
}
where User is a sails-postgres model. I have tried testing it with mocha, sinon and supertest with a test like this
describe('Controller', function() {
var sandbox;
before(function() {
sandbox = sinon.sandbox.create();
sandbox.stub(User, 'findOne');
});
after(function() {
sandbox.restore();
});
describe('GET /confirmid/:id', function() {
it('should do something', function(done) {
request(sails.hooks.http.app)
.get('/confirmid/123')
.expect(200)
.end(function(err,res) {
sandbox.fakes[0].called.should.be.true;
done();
});
});
});
If I leave it at that it errors out because exec is called on undefined, but I can't seem to stub the nested exec method without either errors or the test hanging. Is there a way to stub a series of method calls such as .find().exec()? Or am I best to just leave this to integration tests where I can test it with an actual database?
Assuming that you really want to stub (not just spy) - you want to control what the query resolves to as opposed to simply knowing whether the query was executed. Here's what I'm using to stub sails/waterline query methods. Something like...
var stubQueryMethod = require('stubQueryMethod');
describe('Controller', function() {
before(function() {
stubQueryMethod(User, 'findOne', {
id: 123,
name: 'Fred Fakes'
});
});
after(function() {
User.findOne.restore();
});
describe('GET /confirmid/:id', function() {
it('should do something', function(done) {
request(sails.hooks.http.app)
.get('/confirmid/123')
.expect(200)
.end(function(err,user) {
user.should.have.property('name', 'Fred Fakes');
done();
});
});
});
});
Source: https://gist.github.com/wxactly/f2258078d802923a1a0d
For people looking for other options to stub or mock waterline models, I've found the following four options:
stubQueryMethod.js gist - https://gist.github.com/wxactly/f2258078d802923a1a0d
model mock gist - https://gist.github.com/campbellwmorgan/e305cc36365fa2d052a7
weaselpecker - https://github.com/ottogiron/weaselpecker
sails-mock-models - https://github.com/ryanwilliamquinn/sails-mock-models
After evaluating each one, I've decided on sails-mock-models because it is easy to understand and seems the most used sails mocking library according to npm: https://www.npmjs.com/package/sails-mock-models
Hope this helps someone!
Update: I'm still using sails-mock-models, and it is quite easy, but there are a few drawbacks such as it fails to return promises that are taken into a q.all(promiseArray).then() call. If I get around to investigating the other options or find a workaround, I will post it here.
This will only work for queries that use exec and it overloads all exec calls so if you try to return an error and you have, say, a controller with a policy out front, and the policy does a database lookup, you'll likely go into error there prior to hitting the controller code you intended to test.... that can be fixed with stub.onCall(x), but it is still a bit precarious.
Warnings aside, here's how I've done this in the past:
var path = require('path');
var sinon = require('sinon');
var Deferred = require(path.join(
process.cwd(),
'node_modules/sails',
'node_modules/waterline',
'lib/waterline/query/deferred'
));
module.exports = function () {
return sinon.stub(Deferred.prototype, 'exec');
};
Assuming you have the following service, MyService:
module.exports.dbCall = function (id, cb) {
Model.findOne(id).exec(function (err, result) {
if (err) {
sails.log.error('db calls suck, man');
return cb(err, null);
}
cb(null, result);
});
};
You can test the error case like so:
before(function () {
stub = databaseStub();
});
afterEach(function () {
stub.reset();
});
after(function () {
stub.restore();
});
it('should return errors', function (done) {
stub.onCall(0).callsArgWith(0, 'error');
MyService.dbCall(1, function (err, results) {
assert.equal(err, 'error');
assert.equal(results, null);
done();
});
});

Resources