I'm having difficulty testing that Reflux actions are triggering correctly in my application, and in fact they do not seem to be working at all with Jest. I have this example test:
jest.autoMockOff();
describe('Test', function () {
it('Tests actions', function () {
var Reflux = require('../node_modules/reflux/index');
var action = Reflux.createAction('action');
var mockFn = jest.genMockFn();
var store = Reflux.createStore({
init: function () {
this.listenTo(action, this.onAction);
},
onAction: function () {
mockFn();
}
});
action('Hello World');
expect(mockFn).toBeCalled();
});
});
Which outputs:
● Test › it Tests actions
- Expected Function to be called.
at Spec.<anonymous> (__tests__/Test.js:20:20)
at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)
Even with Jasmine async functions it doesn't seem to be working
jest.autoMockOff();
describe('Test', function () {
it('Tests actions', function () {
var Reflux = require('../node_modules/reflux/index');
var action = Reflux.createAction('action');
var mockFn = jest.genMockFn();
var flag = false;
var store = Reflux.createStore({
init: function () {
this.listenTo(action, this.onAction);
},
onAction: function () {
mockFn();
flag = true;
}
});
runs(function () {
action();
});
waitsFor(function () {
return flag;
}, 'The action should be triggered.', 5000);
runs(function () {
expect(mockFn).toBeCalled();
});
});
});
gives me...
FAIL __tests__/Test.js (6.08s)
● Test › it Tests actions
- Throws: [object Object]
Has anybody made this work?
I figured it out! I just needed to use Jest's own methods for fast-forwarding any timers. i.e. just add the line
jest.runAllTimers();
So the working version of my first example would be
jest.autoMockOff();
describe('Test', function () {
it('Tests actions', function () {
var Reflux = require('../node_modules/reflux/index');
var action = Reflux.createAction('action');
var mockFn = jest.genMockFn();
var store = Reflux.createStore({
init: function () {
this.listenTo(action, this.onAction);
},
onAction: function () {
mockFn();
}
});
action('Hello World');
jest.runAllTimers();
expect(mockFn).toBeCalled();
});
});
Related
My controller file :
define(['app', 'back123','loginService'], function (app) {
app.controller('loginController', function ($scope, $window, loginService, srvAuth) {$scope.emailValidate = function () {
var pattern = /^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/;
if (!pattern.test($scope.Email) ) {
$scope.email_invalid = true;
return false;
}
else {
$scope.email_invalid = false;
return true;
}
};
})
});
My test file:
define(['app', 'jquery', 'angular-mock', 'coreService', 'setterService', 'loginService','logincontroller'], function (App, $) {
describe('app', function () {
beforeEach(module('app'));
describe('logincontroller Email Vaidate', function () {
var scope;
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
$controller("loginController", {
$scope: scope
});
}));
it('sets email false', function () {
scope.email_invalid = false;
scope.Email = 'true';
scope.emailValidate();
expect(scope.email_invalid).toEqual(false);
});
});
});
});
In my browser 'Sources' tab loginCtrl file is loaded which contains logincontroller function
Still getting error
Error: [ng:areq] Argument 'loginController' is not a function, got undefined
Please suggest
Since I have used angularAMD, I updated the code as folows :
angularAMD.inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
$controller("loginController", {
$scope: scope
});
});
Also, I included angularAMD as dependency in define module:
define(['app', 'jquery', 'angularAMD', 'angular-mock', 'coreService', 'setterService', 'loginService', 'loginController'], function (App, $, angularAMD) {
I need to fetch some real data in my tests from a remote url. I Superagent is not being mocked. I have done that by including node_modules/superagent/ in unmockedModulePathPatterns.
This is the file I am trying to test, the .end() function is never called.
This is my test, which fails with a timeout error.
jest.dontMock("../Stocks.js");
jest.dontMock("superagent");
describe("Stock Actions", () => {
var makeRequest = require('../Stocks')
pit("doesn't crash", function () {
var promise = makeRequest("Hello World")
promise.then(function (str) {
expect(str).toBe("yay");
});
return promise;
});
});
And this is the module it's trying to test:
import Reflux from 'reflux';
import request from 'superagent';
console.log("request-superagent", request)
const makeRequest = Reflux.createAction({ asyncResult: true });
const Store = Reflux.createStore({
init() {
this.listenTo(makeRequest, 'onMakeRequest');
},
onMakeRequest(url) {
request('GET', 'http://api.example.com/list/')
.end(function (err, res) {
console.log("res.text", res.text);
if (!res.ok) {
makeRequest.failed("aw");
}
makeRequest.completed("yay");
});
}
});
module.exports = makeRequest;
How do I use superagent in jest-cli?
I'm using jasmine+karma to run the following code...
and get the following error:
Expected { then : Function, catch : Function, finally : Function } to equal 123.
Can someone help me understand why I don't get a resolved value for my promise. thanks
'use strict';
angular
.module('example', ['ui.router'])
.config(function($stateProvider) {
$stateProvider
.state('stateOne', {
url: '/stateOne',
resolve: {cb: function($q) {
var deferred = $q.defer();
deferred.resolve(123);
return deferred.promise;
}},
controller: function($scope, cb) {console.log(' * in controller', cb);},
templateUrl: 'stateOne.html'
});
})
.run(function($templateCache) {
$templateCache.put('stateOne.html', 'This is the content of the template');
});
describe('main tests', function() {
beforeEach(function() {module('example');});
describe('basic test', function($rootScope) {
it('stateOne', inject(function($rootScope, $state, $injector, $compile) {
var config = $state.get('stateOne');
expect(config.url).toEqual('/stateOne');
$compile('<div ui-view/>')($rootScope);
$rootScope.$digest();
expect($injector.invoke(config.resolve.cb)).toEqual(123);
}));
});
});
Ok, Figured it out with some help (via email) from Nikas, whose blog I found at:
http://nikas.praninskas.com/angular/2014/09/27/unit-testing-ui-router-configuration/.
Here is a succinct example that demonstrates how to test the resolve values in ui.router, where the values involve $http.
angular
.module('example', ['ui.router'])
.factory('Clipboard', function($http) {
return {
get: function(args) {
return $http.get('/db/clipboard');
}
};
})
.config(function($stateProvider) {
$stateProvider
.state('stateOne', {
resolve: {cb: function(Clipboard) {
return Clipboard.get();
}}
});
});
describe('main tests', function() {
beforeEach(function() {module('example');});
it('stateOne', inject(function($state, $injector, $httpBackend) {
$httpBackend.whenGET('/db/clipboard').respond({a:1});
$injector.invoke($state.get('stateOne').resolve['cb'])
.then(function(res) {console.log(' *res ', res.data);})
.catch(function(err) {console.log(' *err ', err);});
$httpBackend.flush();
}));
afterEach(inject(function($httpBackend) {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
}));
});
Whatever I do, I always get a stack trace when a chai test fails. I am using chai.config.includeStack = false, as you can see in the following jsfiddle. I have tried chai.Assertion.includeStack = false, also.
http://jsfiddle.net/rhedin/2kk09jka/6/
mocha.setup('bdd');
chai.should();
chai.config.includeStack = false;
describe('"slow tests" of the ACPU', function () {
var expect = chai.expect;
chai.config.includeStack = false;
chai.Assertion.includeStack = false;
it('should say that true is true when I just say so', function () {
expect(true).to.equal(false);
});
});
mocha.run();
Can anyone tell me what's going on?
Thanks.
It appears that Chai won't turn the whole stack on or off if you perform equality tests. However, if you check for falsehood, you can turn the whole stack off. Try this code:
mocha.setup('bdd');
var expect = chai.expect;
var assert = chai.assert;
chai.should();
describe('includeStack false', function () {
before(function () {
chai.config.includeStack = false;
});
it('expect equal', function () {
expect(true).to.equal(false);
});
it('assert equal', function () {
assert.equal(true, false);
});
it('should equal', function () {
true.should.equal(false);
});
it('expect', function () {
expect(true).to.be.false;
});
it('assert', function () {
assert.isFalse(true);
});
it('should', function () {
true.should.be.false;
});
});
mocha.run();
The first 3 tests will have a stack trace. The last 3 tests won't have a stack trace. I could not find documentation or an issue report that explains why it is this way.
I want to test the "addGroup" function using Jasmine. I get the following error:
Error: Expected spy modifyMyHtml to have been called.at null.
I don't know what is the best way to test the addGroup function. Please HELP.....
var myRecord = {
addGroup: function(groupNumber) {
$.when(myRecord.getHtml())
.done(function(returnedHtml){
myRecord.modifyMyHtml(returnedHtml);
});
},
getHtml: function() {
return $.ajax({url: "myHtmlFile.html", dataType: "html" });
},
// adds options and events to my returned HTML
modifyMyHtml: function(returnedHtml) {
$('#outerDiv').html(returnedHtml);
var myOptions = myRecord.getOptions();
$('#optionsField').append(myOptions);
myRecord.bindEventsToDiv();
},
}
====JASMINE TEST
describe("Configure Record page", function() {
var fixture;
jasmine.getFixtures().fixturesPath = "/test/" ;
jasmine.getFixtures().load("myHtmlFile.html");
fixture = $("#jasmine-fixtures").html();
describe("addGroup", function(){
beforeEach(function() {
var groupNumber = 0;
spyOn(myRecord, "getHtml").andCallFake(function(){
return $.Deferred().promise();
});
spyOn(myRecord, "modifyMyHtml");
myRecord.addGroup(groupNumber);
});
it("Should call getHtml", function() {
expect(myRecord.getHtml).toHaveBeenCalled();
});
it("Should call modifyMyHtml", function() {
expect(myRecord.modifyMyHtml).toHaveBeenCalled(); ==>FAILS
});
});
});
You have to resolve the promise before you return em in your andCallFake.
spyOn(myRecord, "getHtml").andCallFake(function(){
return $.Deferred().resolve ().promise();
});
Btw. you should not test that the function on the object you wanna test are called, but that the html in the DOM are set with the right html
it("Should call modifyMyHtml", function() {
spyOn(myRecord, "getHtml").andCallFake(function(){
return $.Deferred().resolveWith(null, 'returnedHtml').promise();
});
expect($('#outerDiv').html).toEqual('returnedHtml')
});