Angular Test tutorials on Jasmine website not working - unit-testing

I just started practice tests on angular-seed app based on Jasmine. When using the first test example found on pivotal.github.io/jasmine/ it fails on my app.
Test example code:
describe("A suite", function() {
it("contains spec with an expectation", function() {
expect(true).toBe(true);
});
});
but passes on tryjasmine.com
I did a test for content and views/partials, they pass. but the one on the jasmine site fails. Am I missing something or is there some config I need to setup?
Karma.conf.js file:
basePath = '../';
files = [
JASMINE,
JASMINE_ADAPTER,
'app/lib/angular/angular.js',
'app/lib/angular/angular-*.js',
'test/lib/angular/angular-mocks.js',
'app/js/**/*.js',
'test/unit/**/*.js'
];
autoWatch = true;
browsers = ['Chrome'];
junitReporter = {
outputFile: 'test_out/unit.xml',
suite: 'unit'
};
Karma-e2e.conf.js file:
basePath = '../';
files = [
ANGULAR_SCENARIO,
ANGULAR_SCENARIO_ADAPTER,
'test/e2e/**/*.js'
];
autoWatch = false;
browsers = ['Chrome'];
singleRun = true;
proxies = {
'/': 'http://localhost:8000/'
};
junitReporter = {
outputFile: 'test_out/e2e.xml',
suite: 'e2e'
};

According to http://pivotal.github.io/jasmine/#section-The_Runner_and_Reporter on the Runner and Reporter section of the doc there is:
document.querySelector('.version').innerHTML = jasmineEnv.versionString();
browser console throws an error
Uncaught TypeError: Cannot set property 'innerHTML' of null
after looking around I found other examples dont have that line. I used the example in tuts+ http://net.tutsplus.com/tutorials/javascript-ajax/testing-your-javascript-with-jasmine/
On that tutorial there is SpecRunner.html it has that block of code without document.querySelector('.version').innerHTML = jasmineEnv.versionString();
and everything works as expected.

You're using old karma's configuration style. I see two options
1) you have quite old karma version,
2) you are trying to run new karma on the old configuration style.
You should try to upgrade karma to the newest version and migrate your configuration to the new style, see: http://karma-runner.github.io/0.10/config/configuration-file.html

You can comment:
document.querySelector('.version').innerHTML = jasmineEnv.versionString();
Or you can add in your body:
<div class='version'></div>

Related

How to mock global Vue.js variable in JEST test

I have a global property/variable with my app urls:
Vue.prototype.$apiUrls = {
root: 'http://localhost:8080/',
api: 'api/v1/'
// etc.
}
I use it inside my components as axios request:
axios.get(`${this.$apiUrls.root}${this.$apiUrls.api}/users/`)
Now I want to test my component's code, I've mocked axios already, but still I receive an error:
TypeError: Cannot read property '$apiUrls' of undefined
I've tried to define/mock this property inside each test and/or in JEST's setup file, like e.g.
global.$apiUrls = {...}
// or
Vue.prototype.$apiUrls = {...}
// or
Object.defineProperties(Vue.prototype, {$apiUrls: {...}})
I've also tried mocking it to window or this (yeah, thats silly), but with no success - I still receive that error - please help.
There is two ways to achieve this. One is using the Config option, as mentioned by #Aldarund. You can read about it here.
If you are using Jest, I recommend doing this in the jest.init.js file:
import { config } from '#vue/test-utils'
config.mocks['$apiUrls'] = {
'some/endpoint'
}
Then add this to the jest section of your package.json:
"setupFiles": [
"<rootDir>/jest.init.js"
]
Now it is globally mocked. If you want to do this on a per test basis, you can use the mocks mounting option:
const wrapper = shallowMount(Foo, {
mocks: {
$apiUrls: 'some/endpoint'
}
})
Hopefully this helps!
If you are interested I am compiling a collection of simple guides on how to test Vue components here. It's under development, but feel free to ask make an issue if you need help with other related things to testing Vue components.
I don't think the answers above work anymore (in 2020).
Here's what worked for me:
For vue-test-utils 1.x.x (Vue 2)
Create a new file, name it eg. jest.init.js
Give it the following content:
import { config } from "#vue/test-utils";
config.mocks["yourGlobalProperty"] = label => label; //you can replace it with your own mock
Add this to your jest.config.js (actually write "rootDir", don't replace anything with a real path)
module.exports = {
setupFiles: ["<rootDir>/jest.init.js"]
}
These files will be only ran before jest runs unit tests.
Note that I'm importing {config}, not the default export. I don't know why the default didn't work for me. Even the documentation for vue test utils doesn't import the default export anymore
Also make sure you're not trying to import from the old vue-test-utils package. (The new one is #vue/test-utils)
For #vue/test-utils 2.x.x (vue-test-utils-next) (Vue 3)
Follow steps like for 1.x.x above, but in step two, do this instead:
import { config } from "#vue/test-utils"; //2.0.0-beta.5
config.global.mocks = {
yourGlobalProperty: label => label
};
You can do it with vue-test-utils beta 15 and later.
Here docs
And some example would be:
import VueTestUtils from '#vue/test-utils'
VueTestUtils.config.mocks['$apiUrls'] = {
...
}

how can I write unit test to my meteor methods?

I found it a little complicated, and more complicated if I wrote my meteor methods in /lib folder, that I want is to test from server test folder my methods (unit test), but stub this.userId and also debugging or showing logs in server side does not help too much.
I was having too much problems with it, I'm using mochajs with velocity, does anyone would help me please? is someone know how can I write the units to meteor methods?
Mocha doesn't support unit tests, only Jasmine does currently. This is an example of how you would write a unit test in Jasmine for the server and use userId.
it("should return premium content to logged in users", function () {
// SETUP
var thisContext = {
userId : true
};
var expectedCursor = 'chapter_cursor1';
var _query = true, _modifiers = true;
Chapters.find = function(query, modifiers) {
_query = query;
_modifiers = modifiers;
return expectedCursor;
};
// EXECUTE
var actualCursor = Meteor.publishFunctions['chapters'].apply(thisContext);
// VERIFY
expect(actualCursor).toBe(expectedCursor);
expect(_query).toBe(undefined);
expect(_modifiers).toBe(undefined);
});
Taken from here: https://github.com/xolvio/Letterpress/blob/master/tests/jasmine/server/unit/chaptersSpec.js#L3

Testing Ember (v1.0.0-rc.3) nested controllers using Mocha and Chai

I am trying to write test cases for controllers of an Ember (v1.0.0-rc.3) Application using Mocha and Chai. One of my controller is making use of another controller as follows
App.ABCController = Em.ObjectController.extend({
needs: ['application'],
welcomeMSG: function () {
return 'Hi, ' + this.get('controllers.application.name');
}.property(),
...
});
I wrote testCase as below:
describe 'ABCController', ->
expect = chai.expect
App = require '../support/setup'
abcController = null
before ->
App.reset()
ApplicationController = require 'controllers/application_controller'
ABCController = require 'controllers/abc_controller'
applicationController = ApplicationController.create()
abcController = ABCController.create()
describe '#welcomeMSG', ->
it 'should return Hi, \'user\'.', ->
msg = abcController.get('welcomeMSG')
expect(msg).to.be.equal('Hi, '+ applicationController.get('name'))
support/setup file is as follows
Em.testing = true
App = null
Em.run ->
App = Em.Application.create()
module.exports = App
Now whenever i try to run testcase i face error
"Before all" hook:
TypeError: Cannot call method 'has' of null
at verifyDependencies (http://localhost:3333/test/scripts/ember.js:27124:20)
at Ember.ControllerMixin.reopen.init (http://localhost:3333/test/scripts/ember.js:27141:9)
at superWrapper [as init] (http://localhost:3333/test/scripts/ember.js:1044:16)
at new Class (http://localhost:3333/test/scripts/ember.js:10632:15)
at Function.Mixin.create.create (http://localhost:3333/test/scripts/ember.js:10930:12)
at Function.Ember.ObjectProxy.reopenClass.create (http://localhost:3333/test/scripts/ember.js:11756:24)
at Function.superWrapper (http://localhost:3333/test/scripts/ember.js:1044:16)
at Context.eval (test/controllers/abc_controller_test.coffee:14:47)
at Hook.Runnable.run (test/vendor/scripts/mocha-1.8.2.js:4048:32)
at next (test/vendor/scripts/mocha-1.8.2.js:4298:10)
Please help me to resolve this issue. I will appreciate if someone provide me few links where i can study for latest ember.js application testing with mocha and chai.
Reading trough the docs I guess your problem is that your expect fails due to this to.be.equal. Try changing the assertion chain to this:
expect(msg).to.equal('Hi, '+ applicationController.get('name'))
Update
After reading your comment I guess the problem in your case is that when you do Ember.testing = true is equivalent to the before needed App.deferReadiness(), so it' obviously necessary to 'initialize' your App before using it, this is done with App.initialize() inside your global before hook. And lastly you call App.reset() inside your beforeEach hook's.
Please check also this blog post for more info on the update that introduced this change.
Hope it helps

Testing service in Angular returns module is not defined

I am trying to run the default service unit test in my project (Taken from the Angular Seed project on GitHub), but I keep getting the error "module is not defined".
I have read that it could be something to do with the order of the referenced JavaScript files, but I can't seem to get it to work, so hopefully one of you might be able to help.
My configuration for the test looks like this:
basePath = '../';
files = [
'public/javascripts/lib/jquery-1.8.2.js',
'public/javascripts/lib/angular.js',
'public/javascripts/lib/angular-.js',
'public/app.js',
'public/controllers/.js',
'public/directives.js',
'public/filters.js',
'public/services.js',
JASMINE,
JASMINE_ADAPTER,
'public/javascripts/lib/angular-mocks.js',
'test/unit/*.js' ];
autoWatch = true;
browsers = ['Chrome'];
junitReporter = { outputFile: 'test_out/unit.xml', suite: 'unit'
};
The service looks like the following:
angular.module('myApp.services', []).
value('version', '0.1');
The test looks like this:
'use strict';
describe('service', function() {
beforeEach(module('myApp.services'));
describe('version', function() {
it('should return current version', inject(function(version) {
expect(version).toEqual('0.1');
}));
});
});
And the error when running the test through testacular is this:
ReferenceError: module is not defined
You are missing the angular-mocks.js file.
I had the same problem, and I understood why it wasn't working:
The jasmine.js javascript must be referenced BEFORE the angular-mocks.js file.
Indeed, the angular-mocks.js checks if Jasmine is loaded, and only if it is it will add the module function to the window.
Here is an extract of Angular Mocks code:
(Edit after the few comments about 'hacking' I had below: this is just an extract of the code, this is not something you need to write yourself, it's already there!)
window.jasmine && (function(window) {
[...]
window.module = angular.mock.module = function() {
var moduleFns = Array.prototype.slice.call(arguments, 0);
return isSpecRunning() ? workFn() : workFn;
/////////////////////
[...]
};
In a nutshell:
Just reference your jasmine.js before angular-mocks.js and off you go.
The window.module function comes in angular-mocks.js and is a shorthand for angular.mock.module. As mentioned in the docs, the module function only works with Jasmine.
Using Testacular, the following example configuration file will load angular-mocks.js.
/** example testacular.conf.js */
basePath = '../';
files = [
JASMINE,
JASMINE_ADAPTER,
'path/to/angular.js',
'path/to/angular-mocks.js', // for angular.mock.module and inject.
'src/js/**/*.js', // application sources
'test/unit/**/*.spec.js' // specs
];
autoWatch = true;
browsers = ['Chrome'];
And, as suggested elsewhere, you can run Testacular with debug logging to see what scripts are loaded (you can also see the same in the inspector):
testacular --log-level debug start config/testacular.conf.js
The angular.mock.inject docs include a pretty complete example.
We use 'module' without 'angular' in our unit tests and it works fine.
CoffeeScript:
describe 'DiscussionServicesSpec', ->
beforeEach module 'DiscussionServices'
beforeEach inject ... etc.
which compiles to
JavaScript:
describe('DiscussionServices', function() {
beforeEach(module('DiscussionServices'));
beforeEach(inject(function ... etc.
The only time I see something like the error you described is if in the testacular.conf.js file the angular-mocks.js file is not listed in the files section before the specs trying to use 'module'. If I put it after my tests in the 'files' list I get
ReferenceError: Can't find variable: module
(Our tests are being run through PhantomJS)
I had included angular-mocks.js in my karma config, but was still getting the error. It turns out the order is important in the files array. (duh) Just like in the head of an html doc, if a script calls angular before it's defined, and error occurs. So I just had to include my app.js after angular.js and angular-mocks.js.
If you're using Yeoman and its angular-generator, you probably get this error. Especially when you do the Tutorial ( ._.)
I fixed it, by copying the angular-mocks.js file, from the bower_components/angular-mocks dir to the test/mock dir. Of course you have to be sure, that your karma.conf.js file is configured correctly.
Greetings!
I had this same issue when I was doing something like var module = angular.module('my',[]). I needed to make sure it was surrounded by IIFE

using mocha testing with cloud9, execute mocha tests from node.js

I was wondering if there is a way to execute mocha tests programmatically from node.js so that I can integrate unit tests with Cloud 9. The cloud 9 IDE has a nice feature where whenever a javascript files is saved, it looks for a file with the same name, ending with either "_test" or "Test" and runs it automatically using node.js. For example it has this code snippet in a file demo_test.js which automatically runs.
if (typeof module !== "undefined" && module === require.main) {
require("asyncjs").test.testcase(module.exports).exec()
}
Is there something like this I could use to run a mocha test? Something like a mocha(this).run()?
The essentials to programmatically run mocha:
Require mocha:
var Mocha = require('./'); //The root mocha path (wherever you git cloned
//or if you used npm in node_modules/mocha)
Instatiate call the constructor:
var mocha = new Mocha();
Add test files:
mocha.addFile('test/exampleTest'); // direct mocha to exampleTest.js
Run it!:
mocha.run();
Add chained functions to programmatically deal with passed and failed tests. In this case add a call back to print the results:
var Mocha = require('./'); //The root mocha path
var mocha = new Mocha();
var passed = [];
var failed = [];
mocha.addFile('test/exampleTest'); // direct mocha to exampleTest.js
mocha.run(function(){
console.log(passed.length + ' Tests Passed');
passed.forEach(function(testName){
console.log('Passed:', testName);
});
console.log("\n"+failed.length + ' Tests Failed');
failed.forEach(function(testName){
console.log('Failed:', testName);
});
}).on('fail', function(test){
failed.push(test.title);
}).on('pass', function(test){
passed.push(test.title);
});
Your mileage may vary, but I concocted the following one-liner a while back and it has served me pretty well:
if (!module.parent)(new(require("mocha"))()).ui("exports").reporter("spec").addFile(__filename).run(process.exit);
Additionally, if you want it to be output in asyncjs format that Cloud9 is expecting, you'll need to provide a special reporter. Here's a really simple example of what a simple reporter would look like:
if (!module.parent){
(new(require("mocha"))()).ui("exports").reporter(function(r){
var i = 1, n = r.grepTotal(r.suite);
r.on("fail", function(t){ console.log("\x1b[31m[%d/%d] %s FAIL\x1b[0m", i++, n, t.fullTitle()); });
r.on("pass", function(t){ console.log("\x1b[32m[%d/%d] %s OK\x1b[0m", i++, n, t.fullTitle()); });
r.on("pending", function(t){ console.log("\x1b[33m[%d/%d] %s SKIP\x1b[0m", i++, n, t.fullTitle()); });
}).addFile(__filename).run(process.exit);
}