角单元测试服务

时间:2018-11-01 13:31:10

标签: angular

我正在努力测试一项简单的服务。我找不到确切的测试内容。

@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就像:

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

this.secondService.makeUrl()返回一个url,而this.firstService.post()实际上是一个http.post请求。

问题是我不知道如何测试deals方法。我嘲笑了FirstServiceSecondService,例如

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

beforeEach (TestBed.configureTestingModule etc)里面的一切都可以,但是我不知道到底要添加什么

 it(...)

我到底要测试什么?如何测试?

1 个答案:

答案 0 :(得分:1)

如果我要按照您的问题中的详细说明在“ MyService”中测试Deals方法,我将模拟并扩展两个依赖项(如您所述),然后更改这些依赖项的结果并确保所有测试用例您要考虑的工作。由于您没有任何错误检查,因此我不会对此进行测试-尽管您确实想在某处(例如在服务中)进行错误检查。我至少会看到三个测试:检查发送给FirstService的调用和参数,检查对SecondService的调用,并检查返回的Observable。

我已经设置了一个测试堆栈闪电,以在此处进行演示:https://stackblitz.com/edit/stackoverflow-q-53102348?file=app%2Fmy.service.spec.ts

这是该堆叠闪电中的MyService描述:

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'});
            })
        });

    });
});