requirejs mocha context error - javascript

I have a simple mocha test that fails when using requirejs and the context config.
Here's A.js
define([], function(){
return {};
});
Here's the test spec.js
var requirejs = require('requirejs');
var localReq = requirejs.config({
baseUrl: "./",
context: "context1"
})
describe("context test", function () {
it("should not throw error", function () {
for (var i = 0; i < 100; i++) {
console.log(localReq("A"), i);
}
});
});
When I run the test mocha spec.js, I get the following error:
Uncaught Error: Tried loading "A" at /Users/khirakawa/work/test/node_modules/mocha/bin/A.js then tried node's require("A") and it failed with error: Error: Cannot find module 'A'
Here's a screenshot:
Notice how A was properly loaded and logged 100 times, yet the test still failed. If I comment out the context config, it works just fine.
Mocha is also printing out '1 passing' and '1 failing', even though there is only 1 test.
Why is this happening?

You could write your test like this:
describe("context test", function () {
it("should not throw error", function (done) {
localReq(["A"], function (f) { done(); });
});
});
As you pointed out in a comment, calling localReq to get a module synchronously should work but for some unexplained reason it does not. The code above, which calls localReq to load the module asynchronously, works.
The reason Mocha is saying that your single test is passing and failing is that it is detecting an error that happens after your test is over and has no other test to associate it with. This kind of error message where the same test both passes and fails is a sure indication that you've got something happening asynchronously but that you have not taken care of it in your Mocha test setup.

Related

Jest gives "Your test suite must contain at least one test" when certain file is imported even though there is a valid test

Whenever I import a certain file from my test file, Jest produces an error that I do not have any tests in the test file, even though there is one with just constants that should pass.
This is running inside a create-react-app folder, but I am using a global install of Jest for the server-side testing.
The Error
FAIL server/__tests__/server.test.js
● Test suite failed to run
Your test suite must contain at least one test.
at onResult (../../../../usr/lib/node_modules/jest/node_modules/#jest/core/build/TestScheduler.js:173:18)
A simplified version of the test file:
const timer = require("./timer.js");
test("should pass", () => {
expect(1 + 2).toBe(3);
});
A simplified version of timer.js:
class Timer {
constructor(ms, onCompleteFunction) {
this.ms = ms;
this.startTime = Date.now();
setTimeout(onCompleteFunction, ms);
}
}
test = () => {
let timer = new Timer(5000, () => console.log("Test Done!"));
};
test();
module.exports = Timer;
(This is a self-answer)
Before adding real testing with Jest, in the Timer.js file I had added a quick test function, just to verify that it was working without running the whole app.
Unfortunately, the function, named test, was not prefixed with var, let, or const. From what I can tell, it overrode the test function from the Jest library, and this error message was the result. When test = 1 or similar was present, the error was
TypeError: test is not a function
This is an extreme edge case due to poor coding practices and something I would have thought was a syntax error on my part, so I don't fault the error message for being unhelpful. I hope this can help someone in the future anyways.

Unknown proider error with karma jasmine unit tests

I have a unit test that is created with the Jasmine framework. When I put a single test specification in the describe block I get a pass in the karma console. If I copy that describe block with the test in it ( the it(); ) then I suddenly start getting problems with dependencies that the module uses.
In the console I get errors around unknown providers.
Here is my simple test:
describe('service definition tests', function () {
it('should be defined', function () {
expect(sut).toBeDefined();
});
});
and that passes okay. If I copy this block I get an error about dependencies. Which is strange as I've already proved that I can test the 'sut' is defined in the first test.
One thing to note is that I have a beforeEach block that loads the module and provides a dependency and it is this dependency that errors when I've duplicated the test. Here is the beforeEach:
var mockConfig = {};
beforeEach(function () {
module('app');
module(function ($provide) {
$provide.value('myConfig', mockConfig);
});
});
the problem has to be something to do with this beforeEach being as the error I get is about the myConfig dependency.
Here is the error:
uncaught Error: [$injecor:unpr] Unknown provider: myConfigProvider <- myConfig <- authorisation
http://errors.angularjs.org/1.4.6/$injector/unpr?p0=myConfiProvider
I managed to resolve this issue by creating a dummy implementation of myConfig factory so that the test files used this.
angular.module('app').factory('myConfig', function() {
var env = 'test';
return {
env: env
}
});
This code lives in a js file that is loaded with the rest of the tests.

Fail Protractor on warnings

I looked through the protractor API and reference conf.js but I couldn't find any documentation on how to fail protractor on warnings or how to turn warnings into errors.
Is either of those possible?
There is nothing built-in in Protractor to treat warnings as errors.
You can redefine the Protractor's log.warn() and throw an error instead of logging a warning:
onPrepare: function () {
var logger = require('protractor/lib/logger.js');
logger.warn = function (message) {
throw message;
};
},
Works for me.
Also, note that:
WARNING - more than one element found for locator ... - the first result will be used
This warning can easily be fixed by replacing the:
element(...)
with:
element.all(...).first()

AngularJS Test a Factory with Mocha

I am new to Mocha and AngularJS Unit Testing but want to test my application using Mocha. I have basic language tests working, but I cannot run tests against my applications Factory or Controller.
I have the following basic files.
apps.js
aangular.module('MyApp', []);
file1.js
angular.module('MyApp').factory('Factory1' ...);
file2.js
angular.module('MyApp').factory('Factory2' ...);
angular.module('MyApp').factory('Controller' ...);
describe('Main Test', function() {
var FactoryToTest;
beforeEach(module('MyApp'));
beforeEach(inject(function (_Factory_) {
FactoryToTest = _Factory_;
}));
describe('Factory2', function () {
it('should return "unknown"', function () {
Game = {};
expect(new Factory2(Game)).to.equal('unknown');
});
});
});
When I run the test, it generates an error, and I am not sure what to fix to get this to work.
Error:
Message:
object is not a function
Stack:
TypeError: object is not a function
at Suite.<anonymous> (b:\app\test.js:5:16)
You're getting an error because the beforeEach function should take a callback function instead of an object. According to the Angular guide on module unit testing (scroll to bottom of the page) :
Each module can only be loaded once per injector. Usually an Angular app has only one injector and modules are only loaded once. Each test has its own injector and modules are loaded multiple times.

How can I use dijit/regisrty in an Intern functional test

I am having problems using any dojo modules with my functional test, I keep seeing window not defined errors or document not defined.
I am currently trying to use the dijit/registry like so (only importing its module so far)..
define([
'intern!object',
'intern/chai!assert',
'require',
'dijit/registry'
], function (registerSuite, assert, require, registry) {
registerSuite({
name: 'login',
'load and login': function () {
return this.remote.get(require.toUrl('http://application.co.uk/'))
.elementById('input1')
.click()
.type("username")
.end()
.elementById('input2')
.click()
.type("password")
.end()
.elementById('rememberMe')
.click()
.end()
.elementByName('Login.Submit')
.click()
.end()
.wait(5000)
.title()
.then(function (title) {
assert.strictEqual(title, 'Application title');
});
}
});
});
...and am getting the following error from node...
$ ./libs/intern/bin/intern-runner.js config=test/intern
Defaulting to "runner" reporter
Listening on 0.0.0.0:9000
c:/.../libs/dojo/_base/unload.js:6
var win = window;
^
ReferenceError: window is not defined
at c:/.../libs/dojo/_base/unload.js:6:11
at execModule (c:\...\libs\intern\node_modules\dojo\dojo.js:512:54)
at c:\...\libs\intern\node_modules\dojo\dojo.js:501:12
at Array.map (native)
at execModule (c:\...\libs\intern\node_modules\dojo\dojo.js:496:17)
at c:\...\libs\intern\node_modules\dojo\dojo.js:501:12
at Array.map (native)
at execModule (c:\...\libs\intern\node_modules\dojo\dojo.js:496:17)
at c:\...\libs\intern\node_modules\dojo\dojo.js:501:12
at Array.map (native)
I have read a previous question about using dojo/text! in a similar way which seemed to indicate the geezer version of Intern could handle this maybe?
The test runs fine without the registry module.
UPDATE
Ok so based on C Snover's response, you cant leverage anything like dijit/registry outside of a webdriver execute() method as the code needs to be within the context of the web browser not the functional test.
Functional tests run from within Node.js, not the browser environment. If you want to access the dijit/registry instance that was loaded in the page you are testing, you need to use execute to run a function within the remote environment:
return this.remote
.get('http://application.co.uk')
.execute(function () {
// this function runs in the browser!
var registry = require('dijit/registry');
// ... do things with registry
return something;
})
.then(function (something) {
// this function runs inside the test runner!
assert.isTrue(something);
});
You won’t be able to define dependencies that have DOM requirements (like dijit/registry) from functional test modules. Only browser-based unit test modules will be able to load such dependencies.
There's also the dijit-intern-helper -> https://github.com/SitePen/dijit-intern-helper
so this
executeAsync(function (done) {
require(['dijit/registry'], function (registry) {
done(registry.byId('titlePane').titleBarNode);
});
})
.then(function (node, setContext) {
setContext(node);
})
.click()
becomes
.then(dijit.nodeById('titlePane', 'titleBarNode'))
.click()
A blog post about it -> https://www.sitepen.com/blog/simplified-dijit-functional-testing/

Categories