Jasmine 2.0 async done() and angular-mocks inject() in same test it()
Solution 1
This should work; I ran into the same problem when I updated to Jasmine 2.0
it("should send get request", function(done) {
inject(function(someServices) {
//some async test
done();
})(); // function returned by 'inject' has to be invoked
});
Solution 2
An IMPORTANT note is the brackets after the inject
call. Eg.
inject(function(someServices) {
//some async test
done();
})(); <-- these brackets here important.
If you look at the type of inject
:
export declare function inject(tokens: any[], fn: Function): () => any;
You can see it returns a function, so you were getting no output because you forgot to call the function!!
If you think about it, it makes sense that it returns a function, because it
takes a function!
So the extra parentheses should solve all problem!
Working Example:
it('should allow you to observe for changes', function(done) {
inject([GlobalStateService], (globalStateService: GlobalStateService) => {
globalStateService.observe("user", storageType.InMemoryStorage, (user: string) => {
expect(user).toBe("bla");
done();
});
globalStateService.write({ user: "bla"}, storageType.InMemoryStorage);
})();
});
Solution 3
To add to the answer of @Scott Boring and to the comment of @WhiteAngel who mentionned that the code inside inject was never called.
This worked for me:
it("should send get request", function(done) {
inject(function(someServices) {
//some async test
done();
})();
});
Solution 4
You could write the test like that:
describe("Some service'", function () {
var service;
var data;
beforeEach(function (done) {
module('app');
inject(function (someService) {
service = someService;
});
service
.getData()
.then(function(result) {
data = result;
done();
});
});
it('should return a result', function () {
expect(data).toBeDefined();
});
}
Solution 5
For Angular 5.2.0: @scott-boring's approach did not work for me. What did work is using the TestBed.get()
to get the services instead of inject()
, as described in the docs:
describe('TooltipComponent', () => {
let component: TooltipComponent;
let fixture: ComponentFixture<TooltipComponent>;
let myService: MyService;
beforeEach(async(() => {
const myServiceSpy = jasmine.createSpyObj('MyService', ['calc']);
TestBed.configureTestingModule({
declarations: [ MyComponent ],
providers: [
{provide: MyService, useValue: myServiceSpy}
]
})
.compileComponents();
myService = TestBed.get(MyService);
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should render correctly', (done) => {
component.render();
setTimeout(() => {
expect(myService.calc).toHaveBeenCalled();
done();
}, 1000);
});
huston007
Updated on July 05, 2022Comments
-
huston007 almost 2 years
My usual test case looks like
it("should send get request", inject(function(someServices) { //some test }));
And Jasmine 2.0 async test should look like
it("should send get request", function(done) { someAsync.then(function(){ done(); }); });
How can I use both done and inject in one test?
-
WhiteAngel about 8 yearsFor me this doesn't work. The code inside
inject
is never being called at all. -
lastoneisbearfood almost 8 years@WhiteAngel, the last time I had the problem you described, it was because some of the required dependencies for my app was missing from karma.conf.js's
files
list. It was impossible to debug this withphantomJS
because it gives nowhere near enough error messages. If you haven't figured out the source of your problem, try using Chrome or FF as your test browser. -
Fabio says Reinstate Monica over 7 yearsI think this is ok as an answer. In any case it would be too long for a comment.
-
dokkaebi over 7 yearsMakes sense. The normal usage of
inject
is to pass its return value (() => any
) in as the second argument toit
, where it is called by jasmine. So we have to call the function returned byinject
if we want it to run! -
dokkaebi over 7 yearsThis didn't work for me. The return value of
inject
is a function, and needs to be called. -
Mirko over 6 yearsI get
inject is not a function
with this -
RMorrisey almost 6 years@WhiteAngel @dokkaebi In the code sample given, the method returned from
inject
is immediately invoked. This is super important! If you forget those two parens at the end, your test code will not be executed.