0

I am struggling to test a simple service. I cannot find out what exactly to test.

@Injectable()
export class MyService {
    constructor(
        private firstService: FirstService,
        private secondService: SecondService) {
    }

    deals(body: myModel): Observable<any> {
        let url = this.secondService.makeUrl('/api/deals');
        return this.firstService.post(url, body);
    }

}

myModel is like:

export class myModel {
    meta: otherModel;
    data: any;
}  

this.secondService.makeUrl() returns a url and this.firstService.post() is actually an http.post request.

The problem is I do not know how to test deals method. I have mocked FirstService and SecondService e.g.

mockFirstService = jasmine.createSpyObj(["post"]);

everything is okay inside beforeEach (TestBed.configureTestingModule etc), but I do not know what exactly to add inside

 it(...)

What exactly do I have to test and how?

1
  • I verify that 1) the service hits the expected endpoint 2) using the expected request method and that 3) the service can handle both a successful and erroneous request. Commented Nov 1, 2018 at 13:38

1 Answer 1

1

If I were looking to test the deals method in 'MyService' as detailed in your question, I would mock and spyon the two dependencies, as you mentioned, and then change the results from those dependencies and be sure all the test cases you want to account for are working. Since you don't have any error checking, I wouldn't test for that - though you do want to error check somewhere, perhaps in the services. I see at least three tests I would do: check the call and arguments sent to FirstService, check the call to SecondService, and check the return Observable.

I have set up a test stackblitz to demonstrate here: https://stackblitz.com/edit/stackoverflow-q-53102348?file=app%2Fmy.service.spec.ts

Here is the MyService describe from that stackblitz:

describe('MyService', () => {
    let myService: MyService;
    let mockFirstService = jasmine.createSpyObj('FirstService', {
        post: of({results: 'Ok'})
    });
    let mockSecondService = jasmine.createSpyObj('SecondService', {
        makeUrl: '/api/deals'
    });

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [/* any imports needed */],
            providers: [MyService,
            { provide: FirstService, useValue: mockFirstService }, 
            { provide: SecondService, useValue: mockSecondService }
            ]
        });
        myService = TestBed.get(MyService);
    });

    it('should be createable', () => {
        expect(myService).toBeTruthy();
    });
    describe('deals() method', () => {
        const testData: myModel = { meta: {}, data: 'test' };

        it('should call secondService.makeUrl()', () => {
            myService.deals(testData);
            expect(mockSecondService.makeUrl).toHaveBeenCalled();
        });
        it('should call firstService.post() with an url and a myModel', () => {
            myService.deals(testData);
            expect(mockFirstService.post).toHaveBeenCalledWith('/api/deals', testData);
        });
        it('should return an Observable that resolves properly', () => {
            mockFirstService.post.and.returnValue(of({results: 'Good'})); // Change return
            myService.deals(testData).subscribe(data => {
                expect(data).toEqual({results: 'Good'});
            })
        });

    });
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.