AngularJS Jamine testing that the broadcast message has been send Only once - angularjs

I'm trying to test that boradcase message been send only once
expect(rootScope.$broadcast.calls.count()).toEqual(1);
The code itself:
$rootScope.$broadcast("page:done_loading");
So, test does not work. I'm not sure about the syntax. Could you help?

First of all you need to set up a spy (you are not showing much code so not sure if you have already done so).
For example:
Jasmine 2.0: spyOn($rootScope, '$broadcast').and.callThrough();
Jasmine 1.3: spyOn($rootScope, '$broadcast').andCallThrough();
Note that and.callThrough() not might be the correct behavior for the spy in your situation.
Then to verify it was called once:
Jasmine 2.0: expect($rootScope.$broadcast.calls.count()).toEqual(1);
Jasmine 1.3: expect($rootScope.$broadcast.callCount).toEqual(1);
Demo (Jasmine 2.0): http://plnkr.co/edit/4xeZOzxOuYNvvASY8jTM

Related

AngularJS Directives - unit tests Karma coverage

I have a problem covering directives unit tests. I used the way from :
http://blog.revolunet.com/blog/2013/12/05/unit-testing-angularjs-directive/ (by Julien Bouquillon)
to create unit tests for my directives. The idea presented on that blog looked great for my needs and well explained, but my issue is that the coverage is not reflected in Karma Coverage(Istanbul code coverage tool).
How should I create my directive unit tests in order to be reflected in coverage summary? Has someone an example that make it possible?
The reason of why you don't see the coverage on the directive code is that, the link you mentioned has used the $compile() and the $digest() called in the beforeEach() through compileDirective() function.
Have that piece of code moved ( the ones that goes into the compileDirective ) into your it() , it should have the coverage done on directive.
Instead of
describe("do some directive testing",function(){
beforeEach(function(){
compileDirective();
});
it('your test code',function(){
//some code here
});
Do the following.
describe("do some directive testing",function(){
beforeEach(function(){
// some other code which execute before each of the it()..
});
it('your test code',function(){
compileDirective();
//some code here
});
So essentially you may have to do some adjustment to your code.
I discovered some issues in my Grunt config file and that's why the coverage wasn't updated. So, the example by Julien Bouquillon is very good and I recommend it.

jasmine test angular.element(document).ready

I have questions concerning how to test the code inside element(document).ready(), during the debug, it seems that the it'll first get to document.ready and then go to the tests and then go inside to the document.ready. I even tried to test in afterEach and find out that the code inside document.ready even happens after the afterEach. Is there any good way to do this kind of test?
I also added the document.ready inside the jasmine tests.
describe('test',function(){
beforeEach(....)
it('test',function(){
angular.element(document).ready(function(){
expect(test).toBe(true);
})
})
})
And in the debug mode it'll goes inside. But when the test runs, it didn't work.
First, I don't think you should use document.ready, because all angular code will execute when document ready as default.
Second, to test this kind of function, you should make the function as a service, then test that service, and in the callback, just call that service.

Printing angular $log statements in Jasmine UTs?

I'm using Jasmine to UT my AngularJS app. It seems to be good practice to use Angular's $log.debug() instead of console.print(), since it can be compiled out.
However, $log messages aren't displayed in my Jasmine UTs, which makes debugging failures difficult.
Is it possible to configure Angular/Jasmine so that the $log messages are collected by the UT runner? Bonus points for function analogous to Python nose's --log-capture, where logs are captured for all tests, but only displayed for failing ones.
This actually isn't hard at all. The gist is that you need to pull $log into your test suite and inject it in your beforeEach() block. Then, you can simply dump messages to console.log in your afterEach() (as below,) or even in your test if you prefer.
describe("MyService", function() {
var MyService, $log;
beforeEach(function() {
inject(function (_MyService_, _$log_) {
MyService = _MyService_;
$log = _$log_;
});
});
afterEach(function () {
console.log($log.debug.logs); //do it here to output for every test...
});
it("should output debug logs", function() {
//do something with MyService that would put a message in $log
expect(true).toBe(true);
console.log($log.debug.logs); //or here to output for just this test!
});
});
For a deeper explanation and examples of writing out other log levels, I'd suggest reading this article (it's where I learned it):
http://www.jvandemo.com/how-to-access-angular-log-debug-messages-from-within-karma/
As to your "bonus points" - I don't know anything about Python, but maybe I can point you in the right direction. If you're running Jasmine 1.x, then I think you can inspect the results of the current test like so: jasmine.getEnv().currentSpec. More details
However, if you're running Jasmine 2.x, then you're facing the same problem as me, as they've hidden that object. Here's a question where I've asked for exactly that.
UPDATE: An answer recently provided to my above question uses Jasmine's reporter functionality to polyfill jasmine.getEnv().currentSpec, so you could indeed use that to only print log statements for failing tests.

AngularJS unit test check if function without methods have been called

I'm using Jasmine to unit test my Angular app. It's pretty easy to test if a method of a function has been called using something like:
spyOn($rootScope, "$emit");
expect($rootScope.$emit).toHaveBeenCalled();
But I can't find a way to check when a function has been called (without a method), for e.g. I'm using $anchorScroll(); in one controller and I have no idea where to apply the above code to this guy. I've seen some Jasmine examples where they were using expect(window.myFunction()).toHaveBeenCalled(), but this doesn't work with Angular's DI.
I can't try it myself at the minute but maybe you could just inject a mock $anchorScroll instead?
var $anchorScroll = jasmine.createSpy('anchorScroll');
$controller('MyCtrl', {
$anchorScroll: $anchorScroll
});
expect($anchorScroll).toHaveBeenCalled();
This should just create a blank spy, one which will take any arguments and do nothing but keep track of the calls for test usage.

Jasmine Testing for AngularJS

Unable to test data returned by Promise variable.In my code there is one factory function drawgraph() in which json data is retrieved by $http service.In controller I am using promise for checking Success Callback and retrieval of data.So I cant get data outside promise.then() function.How I can write jasmine test cases for checking that data values.
I wrote a stackoverflow question and answer to help with this kinda thing.
Check out the link
If this doesnt help you to get started then post some code!
This is an example of unit test - a small art of a unit test - that uses $httpBackend
beforeEach(inject(function ($httpBackend, Products, PATH) {
httpBackend = $httpBackend;
httpBackend.when('JSONP', PATH.url + 'products?callback=JSON_CALLBACK').respond(PRODUCTS);
}));

Resources