MadCatm2
MadCatm2

Reputation: 1001

Test observable return value of method with Jasmine

I am new to Jasmine and I am attempting to write a simple unit test that checks if my method returns the intended value. Here is the method in my Angular application:

saveEvent(techEvent): Observable<IEvent>{

        let headers = new Headers({ 'Content-Type': 'application/json'})
        let options = new RequestOptions({headers: headers})

        return this.http.post('/api/events', techEvent, options)
            .map((response: Response) => {
                //have an updated copy of saved event
                return response.json()
            }).catch(this.handleError)  
}

As you can see, it is a post method that saves a 'techEvent' object. Here is the test I have attempted to write in my spec:

   it('should save the event', () => {

        var testEvent = { id: 7, name: "AngularJS"}

        mockHttp.post.and.returnValue(Observable.of(false))

        techEventService.saveEvent(<IEvent>testEvent)

        expect(techEventService.saveEvent).toBe(jasmine.any(Object))

    })

This test fails :( . My goal here is to simply test that the method returns an object and returns the specific object that is passed. I wonder if I could also test if it is a JSON...

Upvotes: 3

Views: 8648

Answers (1)

Jason Spradlin
Jason Spradlin

Reputation: 1427

Your method is asynchronous, which is generally the case for Observables. You'll want to subscribe to the response from techEventService.saveEvent and verify that the variable was changed within that subscribe callback.

Additionally, you're testing whether techEventService.saveEvent is an object, but that is most definitely a reference to the techEventService.saveEvent function. I believe you wanted to test if the response from the server was an object, which is another reason to run your test within the subscribe() callback.

it('should save the event', (done) => {

    var testEvent = { id: 7, name: "AngularJS"};

    mockHttp.post.and.returnValue(Observable.of(false));

    techEventService.saveEvent(<IEvent>testEvent).subscribe((response) => {
       expect(response).toBe(jasmine.any(Object));
       done();
    });
});

Because this is async, jasmine might think the test is done before your callback is actually loaded (never even reaching the expect call, and declaring your test a pass without having run it.) For that reason, you can pass in done into your test, and then jasmine won't consider your test to have completed until you call the done() callback.

Side note: Make a habit of ending lines with semicolons when appropriate.

Upvotes: 5

Related Questions