I'm going through some of the examples online for AngularJS to try to understand how it works. I'm trying to use jasmine to test like in the examples. In my spec file, I have:
var Person = function (name, $log) {
this.eat = function (food) {
$log.info(name + " is eating delicious " + food);
};
this.beHungry = function (reason) {
$log.warn(name + " hungry " + reason);
};
};
var bob = new Person();
describe("describe", function () {
it("$q", function () {
var pizzaOrderFulfillment = $q.defer();
var pizzaDelivered = pizzaOrderFulfillment.promise;
pizzaDelivered.then(bob.eat, bob.beHungry);
pizzaOrderFulfillment.resolve("resolved");
$rootScope.$digest();
expect($log.TypeInfo.logs).toContain(["resolved"]);
});
});
I get
ReferenceError: $q is not defined
Am I using Jasmine correctly? I basically am just writing all my angular and jasmine code in the spec.js file. When I had the angular code in another file, my spec.js file couldn't find it. Probably because I didn't set any dependencies up on what gets loaded first since I'm just starting out with this stuff.
Edit, fixed the $ to be $q and the referencerror.
I guess you are not injecting the $q service in your unit test.
For example in your beforeEach block you can inject it:
var q;
beforeEach(inject(function($q) {
q = $q;
}));
And then in your unit test:
describe("describe", function () {
it("$q", function () {
var pizzaOrderFulfillment = q.defer();
var pizzaDelivered = pizzaOrderFulfillment.promise;
pizzaDelivered.then(bob.eat, bob.beHungry);
pizzaOrderFulfillment.resolve("resolved");
$rootScope.$digest();
expect($log.TypeInfo.logs).toContain(["resolved"]);
});
});
Related
I am writing some end-to-end tests with Protractor for and Angular app. I am currently trying to mock some http responses using angular-mock and am running into a problem with scoping that I don't understand.
var protractor = require('protractor');
var ngMockE2E = require('ng-mock-e2e');
var testData = require('./e2e-data.json');
describe('DataEater', function() {
var $httpBackend = ngMockE2E.$httpBackend;
var appUrl = browser.baseUrl + 'scheduler/data-eater/';
var self = this;
self.testData2 = require('./e2e-data.json');
beforeEach(function() {
browser.get(appUrl);
ngMockE2E.addMockModule();
ngMockE2E.addAsDependencyForModule('dataEater');
$httpBackend.when('GET', '/scheduler/tasks/queue/')
.respond(function(method, url, data) {
console.log(testData);
console.log(self.testData2);
return [200, self.testData.history, {}];
});
Why are neither testData or testData2 defined? How can I get this data scoped properly so that I can return it as part of the response?
The problem might be that you need to explicitly pass the $scope to your controller. Try something like the following code:
beforeEach(
inject(function (_$controller_, _$rootScope_) {
myController = _$controller_('myControllerName', {
$scope: _$rootScope_.$new()
});
})
);
I'm building a command-line application in NodeJS and I want to thoroughly test it using Jasmine.
I've implemented a promptUser() method which uses Node's readline.createInterface method to pose a question and pipe the response into a callback. I want to test that, given a user response of 'q', my module's quit() function is called.
However I'm struggling to test this. I don't really want to test the readline method directly, since I didn't write that code, but I reasoned that if I can create a listener on process.stdout.write then when enter command: is printed to the screen I can respond with process.stdin.write("q\n") and trigger the if/else logic.
I've simplified the code, but should explain what I'm trying to do:
Module source code:
var Cli = function() {
var rl = require('readline');
var self = this;
Cli.prototype.promptUser = function() {
var inputHandler = rl.createInterface(process.stdin, process.stdout);
inputHandler.question('enter command: ', function(answer) {
if (answer === 'q') {
self.quit();
};
});
};
Cli.prototype.quit = function() {
// doSomething
};
};
module.exports = Cli;
Jasmine test:
var Cli = require('Cli');
describe('My application.', function() {
beforeEach(function() {
cli = new Cli();
spyOn(cli, 'quit');
});
describe('Cli #promptUser', function() {
it('input of lower-case q calls cli.quit()', function() {
process.stdout.once('write', function() {
process.stdin.write("q\n");
});
cli.promptUser();
expect(cli.quit).toHaveBeenCalled();
});
});
});
I'm looking to either make this approach work or find a better way to test my code. I suspect there is probably a superior/more direct approach.
I've created a simple logging service in Angular:
app.service('$userInteraction', [function() {
var userLog = "";
this.log = function (datetime, screen, logMessage) {
userLog.concat(datetime + "\t" + screen + " Screen\t" + logMessage + "\n");
}
this.getLog = function () {
return userLog;
}
this.clearLog = function () {
userLog = "";
}
}]);
And I use it in one of my controllers like so:
app.controller('myController', ['$scope', '$userInteraction', function($scope, $userInteraction) {
$userInteraction.log(Date(), 'Login', 'Some random message.');
}]);
But when I run my code I get the following error:
TypeError: $userInteraction.log is not a function
Though I could've sworn that it worked before. I'm fairly new to Angular so this might very well be a newbie mistake. Thanks in advance!
this question is old, but help someone... You code run on plunker, problably you have duplicate services name... Check all files angularjs and verify if exist another service with same name.
I had similar problem. Two services with same name and call did not have function called.
I'm new to unit testing, so please forrgive me if my question could be silly. I wrote an unit test using Mocha with PhantomJS and Chai as assertion library. The code that I want to test is the following function:
function speakingNotification(audioStream){
var options = {};
var speechEvents = hark(audioStream, options);
speechEvents.on('speaking', function() {
return 'speaking';
});
speechEvents.on('stopped_speaking', function() {
return 'stopped_speaking';
});
}
As you can see it takes an audioStream parameter as input and then use a librabry called hark.js https://github.com/otalk/hark for detecting speaking events. The function should return if the user is speaking or not.
So I wrote the following unit test:
describe('Testing speaking notification', function () {
describe('Sender', function(){
var audio = document.createElement('audio');
audio.src = 'data:audio/mp3;base64,//OkVA...'; //audio file with sound
var noAudio = document.createElement('audio');
noAudio.src = 'data:audio/mp3;base64,...'; //audio file with no sound
it('should have a function named "speakingNotification"', function() {
expect(speakingNotification).to.be.a('function');
});
it('speaking event', function () {
var a = speakingNotification(audio);
this.timeout( 10000 );
expect(a).to.equal('speaking');
});
it('stoppedSpeaking event', function () {
var a = speakingNotification(noAudio);
this.timeout( 10000 );
expect(a).to.equal('stopped_speaking');
});
});
});
The test fails and shows:
AssertionError: expected undefined to equal 'speaking'
AssertionError: expected undefined to equal 'stopped_speaking'
I also tried to use done() insted of the timeout, however the test fails and shows:
ReferenceError: Can't find variable: done
I searched for tutorials, however I can only find simple examples that don't help.
How can I write a correct test?
Does anyone know if you can add a second service to an angular module?
It seems when I try, I end up breaking angular.
This Works:
var MyModule = angular.module('MyModule',[]);
MyModule.service('MyService',function(){
this.message = 'checking in';
});
MyModule.controller('MyController', function($scope,MyService){
console.log(MyService.message);
});
// output
// checking in
This DOES work: I had an issue elsewhere in my code. I'm leaving this up because it is still hard to find angular documentation with two services being applied (which I promise I looked for)
var MyModule = angular.module('MyModule',[]);
MyModule.service('MyService',function(){
this.message = 'checking in';
});
MyModule.service('MyServiceTwo',function(){
this.message = 'checking in';
});
MyModule.controller('MyController', function($scope,MyService,MyServiceTwo){
console.log(MyService.message);
});
// no output
In your second service definition just retrieve the module - don't redefine it:
var MyModule = angular.module('MyModule');