mocha full coverage test using json schema - javascript

I have written a test for a get request, but want to get "full coverage" for this test. Basically, I want to use something like JSON Schema to validate that the JSON return matches my expectations.
My code so far is below:
var winston = require('winston');
//var chai = require('chai');
var request = require('supertest-as-promised');
var testUtils = require('./utils/test_utils');
var API_ROOT = 'http://localhost:8000/mywebsite';
var agent = request(API_ROOT);
describe('/my-profile/', function(){
describe('GET', function() {
var url = '/my-profile/';
it('should return valid payload', function(done) {
agent.
get(url).
set('Content-Type', 'application/json').
expect('Content-Type', /json/).
expect(200).
// then(testUtils.logResponse).
then(function(res) {
done();
}).catch(function(err) {
// winston.log(res).then(done);
done(err);
});
});
});
});
How do I go about using json schema for validate. Any sample links? comment? code?

You might try using Chai json-schema plugin. Which let's you make assertions like the following:
expect(goodApple).to.be.jsonSchema(fruitSchema);
expect(badApple).to.not.be.jsonSchema(fruitSchema)
See the website for full details.

You say you want to use something "like" json schema to validate the returned JSON, well, Chai assertions would suit the task just fine.
Just test for the presence of properties with the property chain, or check that they are of the correct type with the instanceof chain. If you know exactly what the api should return for a given test case, construct a matching object and compare it with the deep chain.

Related

Winston Logger return exact logged string

I'm using Winston to do logging for my node application. I'm trying to achieve grabbing exactly value Winston logged into the log file. Example in this scenario it will return :-
{"message":"New S3!","level":"info"}
I've tested to console log the function and check certain package function in the winston, so far couldn't find any way to return it.
var logger = winston.createLogger({
transports: [
transport, //This is to upload to
new winston.transports.File(options.file), //Will log into file
new winston.transports.Console(options.console) //Will log at console display
]
});
var loggedVal = logger.info('New S3!');
console.log(loggedVal);
I had the same problem for testing output of console transport. So the solution is valid for jest env only.
We can use jest-mock-process package as described there
Or create simple spies
const mockStdoutWrite = jest.spyOn(process.stdout, 'write').mockImplementation(function () { return true; });
const mockStdout = jest.spyOn(console, 'log').mockImplementation(function () { });
logger.debug('Debug message');
expect(mockStdoutWrite).toHaveBeenNthCalledWith(1, ....);
Winston logger wasn't designed to do what you're trying to achieve, and there are hardly any use cases for what you're trying to do so I doubt winston would have that feature.

Mocha Unit Test with Jquery Submit

I'm working on creating a Mocha unit test based on solution code that was given to me by someone else. (The goal here is to create an online code assessment for students that will be run against my unit test). It's a simple exercise and will not be extensible at all in the future.
I want to get the return value from a jQuery on-submit event and use that for my test case but am unsure how I can do that given the solution code that was given to me to work from.
I've gone through the document here (https://gist.github.com/soheilhy/867f76feea7cab4f8a84) but my particular case is different since we are using jQuery's on document ready and the on-submit.
I've also tried to do something like "export.validate = function(){}" to match an example from the docs but everything I've tried I either get that Mocha doesn't know the function, or Mocha doesn't know the boolean variable references.
solutionCode.js
$(document).ready(function() {
$("#form-submit").on("submit", function () {
var xValid = true;
var yValid = true;
//...Bunch of logic here that could change the boolean values...
return xValid && yValid;
});
});
And here is my Mocha test file.js
this.jsdom = require('jsdom-global')()
global.$ = global.jQuery = require('jquery');
var assert = require('assert');
var work = require('path/to/solutionCode.js');
describe('Validate Form', function() {
it('Form is valid', function(done) {
//Not sure how to get the return value here to do my assertion...
done();
});
});
If the value of both booleans in the return are True, the test should pass, otherwise it should fail.

Using external test data in protractor test

I am trying to reference test data using a JSON but it appears as undefined. I am trying to use a Page Object Model and reference external test data. When referencing the values in my test data and passing into a function they are appearing as undefined
I have a simple JSON like:
[{
"userNameValue": "mrUserUser",
"passwordValue": "i_am_correct"
}]
My tests then look like:
'use strict';
var testData = require('./testData/testData.json');
var AngularPage = require('./pages/logon.page.js');
describe('travel portal logon page', function () {
var logonPage;
beforeEach(function () {
logonPage = new AngularPage();
});
it('should fail to logon', function() {
logonPage.loginToSite(testData.userNameValue, testData.passwordValue);
expect(logonPage.errorMessageText).toEqual('Invalid Login');
});
});
Both testData.userNameValue and testData.passwordValue are being written as undefined. I have also tried referencing using the other format of testData['userNameValue'].
Am I missing something?
Please help, thanks
Make sure you have exported your testData.json file as required using module.exports function. Also your test data is not an object in the first place, its an array. In order for your test script to work, change the test data into an object. Here's how -
var testData = {
"userNameValue": "mrUserUser",
"passwordValue": "i_am_correct"
};
If you want to keep the testData the way it is now(an array), then change the way you access the data in your test steps. Here's how -
logonPage.loginToSite(testData[0].userNameValue, testData[0].passwordValue);
Hope it helps.

Adding test IDs to unit tests for reporting

I'm using mocha and trying to build a testing system which reports tests individually. The goal is to have traceability between tests defined in the requirements for the project and unit tests. So, for example, the test 'Must be able to create new widgets' is in the requirements database with id of '43', I want the unit test which tests that criteria to report something like Test 43, Must be able to create new widgets, pass, and then update the corresponding db entry (another service could be responsible for this).
Can this be done in mocha? The only thing I've found so far is to replace text in the it() function with the test id, and use the json reporter to process the results afterwards (but then I don't get the text for what is being tested, unless I combine them and do some kind of parsing). Note: not all tests would have an id.
Here's an example of the kind of functionality I'm hoping for
describe("Widget" function() {
it("should allow creation of widgets", function() {
this.id = 43;
result = widget.create();
expect.result.to.exist;
});
});
And then either a hook, like
afterEach(function(test) {
if (test.hasOwnProperty('id')) {
report(test.result);
}
});
Or a custom reporter, or an adapter of some sort.
runner.on('test end', function(test) {
console.log(test.id); //doesn't exist, but i want it to
report(test);
});
This depends on your assertion library.
With Chai, you havethe optional field for text.
assert.should.exist(result, 'expect Result to exist (Id 43)');
With Jasmine, you can add the test reference to your it():
describe("Widget" function() {
it("should allow creation of widgets (Id 43)", function() {
To use the Mocha custom reporters you could try to define one in your test suite.
module.exports = MyReporter;
function MyReporter(runner) {
var passes = 0;
var failures = 0;
runner.on('pass', function(test){
passes++;
console.log('pass: %s', test.fullTitle());
});
runner.on('fail', function(test, err){
failures++;
console.log('fail: %s -- error: %s', test.fullTitle(), err.message);
});
runner.on('end', function(){
console.log('end: %d/%d', passes, passes + failures);
process.exit(failures);
});
}
There are really 2 suggestions here. The first is the simplest, and is to simply add your id to the description of the it() and then that will show you what has passed and failed. That would be the quickest way to reach your goal.
However, if you wanted to have the fancier method, and could test to ensure things are set, then you could use the custom reporter, which would allow you to fail a test if the ID was not set.
What I wanted and what exists were so close! I was able to solve this using the ctx property of the test in the reporter, e.g. test.ctx.id
test.js
describe("Widget" function() {
it("should allow creation of widgets", function() {
this.id = 43;
result = widget.create();
expect.result.to.exist;
});
});
reporter.js
runner.on('test end', function(test) {
console.log(test.ctx.id);
report(test);
});

Structure for unit testing on node.js with mongoose

I've been developing with node.js for months but now I'm starting a new project and I'd like to know how to structure the app.
My problem comes when talking about unit testing. I will use nodeunit to write unit tests.
Also I'm using express to define my REST routes.
I was thinking about writing my code that access databases in two "separate" files (They will be more, obviously, but I'm just trying to simplify the code). There will be the routes code.
var mongoose = require('mongoose')
, itemsService = require('./../../lib/services/items-service');
// GET '/items'
exports.list = function(req, res) {
itemsService.findAll({
start: req.query.start,
size: req.query.size,
cb: function(offers) {
res.json(offers);
}
});
};
And, as I'm using there, an item service used just to access data layer. I'm doing this to test only data access layer on unit testing. It'll be something like this:
var mongoose = require('mongoose')
, Item = require('./../mongoose-models').Item;
exports.findAll = function(options) {
var query = Offer
.find({});
if (options.start && options.size) {
query
.limit(size)
.skip(start)
}
query.exec(function(err, offers) {
if (!err) {
options.cb(offers);
}
})
};
This way I can check with unit testing if it works correctly and I can use this code everywhere I want. The only thing I'm not sure if it's been correctly done is the way I pass a callback function to use returned value.
What do you think?
Thanks!
Yes, quite easily!
You can use a unit testing module like mocha and either node's own assert or another such as should.
As an example of a test case for your example model:
var ItemService = require('../../lib/services/items-service');
var should = require('should');
var mongoose = require('mongoose');
// We need a database connection
mongoose.connect('mongodb://localhost/project-db-test');
// Now we write specs using the mocha BDD api
describe('ItemService', function() {
describe('#findAll( options )', function() {
it('"args.size" returns the correct length', function( done ) { // Async test, the lone argument is the complete callback
var _size = Math.round(Math.random() * 420));
ItemService.findAll({
size : _size,
cb : function( result ) {
should.exist(result);
result.length.should.equal(_size);
// etc.
done(); // We call async test complete method
}
},
});
it('does something else...', function() {
});
});
});
And so on, ad nauseum.
Then when you're done writing your tests - assuming you've $ npm install mocha'd - then you'd simply run $ ./node_modules/.bin/mocha or $ mocha if you used npm's -g flag.
Depends how rectal/detailed you want to be really. I've always been advised to, and find it easier to: Write the tests first, to get a clear specification perspective. Then write the implementation against the tests, with any extra insight a freebie.

Categories

Resources