I'm using Mocha + Chai (with ChaiAsPromised plug-in) to test my backend node application.
I want to test for errors in a certain unit. I am expecting to get undefined, and fail on any other output.
For example:
it('should fail creating without name', done => {
var errors = models.Alias.build({
AssociationId: faker.random.number()
}).validate();
expect(errors).to.eventually.not.exist.notify(done);
})
If the test fails, I see this output:
1) Models: Alias should fail creating without name:
AssertionError: expected { Object (name, message, ...) } to not exist
I wish to display more details about the Object and the failure reason. How can I tell mocha/chai to print the Object with its fields and content?
Related
I'm using TypeScript and Jest to write unit tests. When I tried to run them, I got the following error messages:
Test suite failed to run
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
SyntaxError: C:\..\my\file\name.web.spec.ts: Unexpected reserved word 'yield'.
This came from an original TypeScript section like the following:
it("should do things right", () => {
const payload = { ... };
await manager.init(payload);
});
The solution seems obvious in retrospect when looking at the code, but easy to miss. I just simply needed to make the function async.
it("should do things right", async () => {
const payload = { ... };
await manager.init(payload);
});
Lead:
New to working with typescript and writing unit tests using Mocha and Chai.
Question
Any tips on how I can go about getting 100% line coverage in unit tests with an object literal that isn’t in a class? Trying to avoid going static if at all possible, but unit testing still has to hit 100% to pass.
// constants.ts
export default {
path: “./example”,
name: “Example Name”
}
// constants.spec.ts
// How do I unit test ‘export default’ for 100% line coverage?
// I have tried
import chai from "chai";
import * as constants from “./constants.ts”;
describe(“constants”, () => {
it(“Constants literals should have a length of 2“, () => {
chai.expect(constants.default.length).equal(2);
});
});
// The mocha test succeeds, but the line still says it hasn’t been tested.
I think I found the answer, but I am sure there is an easier way to use and test literals in Typescript.
describe("Constants", async () => {
it("can be created", async () => {
const obj = constants.default;
chai.should().exist(obj);
});
});
Typescript Mocha Chai unit-test 100% line coverage
Tl;dr:
npx -p chai -p mocha mocha test.js yields Error: Cannot find module 'chai'
Question: I can't use chai here? Because..?...It's not executable?
Context:
I thought a nice use of npx would be to write example tests and code together in one file and run those tests (seems ideal for letting people get their hands on tdd without worrying too much about the surrounding ecosystem.)
This mocha example works great:
// addOne/test.js
const assert = require('assert')
function addOne(num){
return isNaN(num) ? 'not a number' : num+1
}
describe('addOne', function() {
it('returns a number increased by a value of 1' , function(){
assert.equal(addOne(0), 1)
assert.equal(addOne(-1), 0)
assert.equal(addOne(.1), 1.1)
})
it('returns the message "not a number" if given a non-number value', function(){
assert.equal(addOne('foo'), 'not a number')
assert.equal(addOne(function(){return 2}), 'not a number')
})
})
(In root of directory addOne run npx mocha test.js)
HOWEVER
what if I wanted to use an expectation library, like chai's 'expect'?
var chai = require('chai')
var expect = chai.expect
< function >
describe('addOne', function() {
it('returns a number increased by a value of 1' , function(){
expect(addOne(0)).to.equal(1)
< etc >
Knowing I can install multiple packages with npx I have tried running
npx -p chai -p mocha mocha test.js
but get: Error: Cannot find module 'chai'
Have I hit a limitation of npx? Must all packages you provide it be executable?
I wanted to run some Spectron e2e tests I wrote some weeks ago, but to my surprise, suddenly they all stopped working for one and the same reason.
According to the error message, I'm dealing with rejected Promises, but I can't figure out where the problem is coming from. Calling done at the end of my testcase raises the exact same error.
I'm running the following command to launch my test suit: mocha test/e2e
Mocha then executes this index.js before running my tests in ordner to support ES6+ features
'use strict'
//index.js
// Set BABEL_ENV to use proper env config
process.env.BABEL_ENV = 'test'
// Enable use of ES6+ on required files
require('babel-register')({
ignore: /node_modules/
})
// Attach Chai APIs to global scope
const { expect, should, assert } = require('chai')
global.expect = expect
global.should = should
global.assert = assert
// Require all JS files in `./specs` for Mocha to consume
require('require-dir')('./specs')
After that its trying to run this small Login.spec.js which returns the error mentioned above
import utils from '../utils'
import {Application} from "spectron";
import electron from "electron";
describe('🔑 Login', function () {
this.timeout(11000);
it('login form exists', async function (done) {
this.app = new Application({
path: electron,
env: {"SPECTRON_RUNNING":true},
args: ['dist/electron/main.js'],
startTimeout: 10000,
waitTimeout: 10000
})
await this.app.start()
await this.app.client.windowByIndex(1);
done();
})
})
I've been beating my head all morning on this and I'm pretty sure I'm just missing something simple. It appears I'm getting a new object ({}) for a return value when I'm expecting a string, but even if I hard code a string for a return value I get the same error.
I've worked through the examples found here with no trouble. My package.json is set to test properly (or at least I don't think that's the problem, but I can post it as well if it'll help troubleshoot my problem). I'm new-ish to Node.js (but well experienced with JS) & just learning Mocho & Chai.
What am I missing? Why am I getting what appears to be an empty object when I should be getting a string? What's causing the test to fail?
I've written a simple API to get the username from a host PC:
const username = require('username');
exports.getUserName = function() {
console.log(username.sync());
return username.sync();
};
And I've written a test using Mocha & Chai:
var expect = require("chai").expect;
var getUserName = require('./username.js');
describe("User name API", function () {
it("Returns a string with the user's name", function () {
expect(getUserName).to.be.a('string');
});
});
Here's the error that's returned when I run the test with npm test:
> sbserialwidget#0.0.1 test C:\deg\node_modules\sbSerialWidget
> mocha --reporter spec
running
User name API
1) Returns a string with the user's name
0 passing (13ms)
1 failing
1) User name API Returns a string with the user's name:
AssertionError: expected {} to be a string
at Context.<anonymous> (C:\deg\node_modules\sbSerialWidget\test\username.js:6:29)
at callFn (C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runnable.js:334:21)
at Test.Runnable.run (C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runnable.js:327:7)
at Runner.runTest (C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runner.js:429:10)
at C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runner.js:535:12
at next (C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runner.js:349:14)
at C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runner.js:359:7
at next (C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runner.js:285:14)
at Immediate._onImmediate (C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runner.js:327:5)
If I change the test to expect an object, the test works: expect(getUserName).to.be.an('object');.
However if I do a console.log(typeof username.sync()); it says it's a string.
What do I need to do to fix this?
Edit for solution:
Here's the code that I eventually got to work. I think part of the problem was a path issue (I'm in a Windows environment), partly me simply not quite understanding what needed to be done, and finally me not understanding how to call the function properly in the test (see below).
Here's the modified username.js code:
const username = require('username');
exports.getUserName = function() {
console.log(username.sync());
return username.sync();
}
Here's the modified usernametest.js:
var expect = require("chai").expect;
//here's where one point of confusion was, I was trying to call the original getUserName()
//function, but it's been turned into a variable called username
var username = require('..\\js\\username.js').getUserName;
describe("User name API", function () {
it("returns a string with the user's name", function () {
//so here, instead of calling username.getUserName(), I call username()
//instead. Voila, it works...
expect(username()).to.be.a('string');
});
});
you are not executing the function
change
expect(getUserName).to.be.a('string');
to
expect(getUserName()).to.be.a('string');
edit
I din't figure out that your are exporting an object
exports.getUsername = function(){...}
should be
expect(getUserName.getUserName()).to.be.a('string');
thanks to #robertklep