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.
Related
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.
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.
I'm using Jasmine to write unit tests for our controllers, but wanted to get community feedback on how to handle this situation...
I have a controller - InvoiceController, like this:
angular.module('myModule').controller('myController', ['$scope',
function($scope) {
$scope.doSomething = function() {
$scope.something = 'bar';
};
}
]});
In my unit tests I verify that my controller has the expected methods:
it('should be able to do some work', function() {
// initialize scope properties
scope.someProperty = 'foo';
// load controller using those properties
injectController();
// do I have all of the functions necessary to do this work?
expect(typeof (scope.doSomething)).toBe('function');
// now execute test
scope.doSomething();
expect(scope.something).toBe('bar');
}
And finally, in my html I have an element with an ng-click, like this:
<button ng-click="doSomehing()">Do Something</button>
Looks good, right? BUT, did anyone catch what I did wrong?
My ng-click method is misspelled, but all tests are green and life seems rosy...until I try to click on that guy and nothing happens. No render time error, no error on click. Hmm.
Several times now as I'm refactoring code this has got me. I rename doSomething to doSomethingCooler in the unit test and in the controller but miss a place in the html. After a minute of head scratching I see what was missed.
I'd love a way to ensure that the markup is valid. E2E tests seem to be the obvious solution, but those are prone to fragility so we are hoping there are some alternatives.
If this were ASP.Net I would attach the click events from code behind so that I would get compile time errors vs run time errors.
Thoughts??
Thad
One thing you could do is get the template text and run $compile on it. And then link it to your controller's scope. Then you could do something like dom.find('[ng-click]').click();, which should throw if any of them is not defined in your controller's scope. This is similar to how you generally test directives.
In my app I have a $timeout that fires every minute and schedules another $timeout. Because of this my e2e tests wait for $timeout and don't want to work at all. As I understand there is no way to say karma not to wait for certain $timeout. But is there a way to detect that code is running in karma environment and don't run this $timeout at all?
I didn't find any elegant solution. For now I decided to pass a flag in a url, parse it and disable this special $timeout depending on this flag. This solution doesn't look good but it works. I hope later angular will have some kind of e2e dsl commands for this kind of things.
From AngularJS docs:
In tests you can use $timeout.flush() to synchronously flush the queue
of deferred functions.
If you call many $timeouts, you can use the waitsFor jasmine function. Something like this:
waitsFor(function () {
$timeout.flush();
return workedThreeTimes();
}, 'should run something per minute', 1000 * 60 * 3);
(sorry for my english)
I want to test if a directive binds the correct jquery functions to the DOM and that they work.
For instance i want to test if an element is visible after it was slid up with $.slideUp() or i want to execute a click event on an html input.
It seems that i need to somehow attach the compiled directive to the DOM to make this happen. I've watched the testing directives video on youtube where he says that it is possible but he doesnt mention how you do it.
I'm kinda stuck.
Heres the link to the failing test: http://plnkr.co/edit/PojXf8?p=preview
Couple of things:
First, if you want to use jQuery with Angular, it needs to be loaded before Angular is, so move its script tag before Angular's.
Second, you're right about attaching the directive to the DOM. In a beforeEach call, you can use jQuery to create a host div and then remove that div in an afterEach call.
Here that is in a fork of your plunk.
That said, you only need your div in the DOM to check for visibility, which I'm not even sure you need to do in most cases. For example, you could use Sinon to spy on the slideUp call to make sure it happens and rely on jQuery's tests that it actually works.
And you can always trigger clicks directly just by calling elm.click() using jQuery.