Testing Service. TypeError: done.fail is not a function

别说谁变了你拦得住时间么 提交于 2019-12-24 07:08:10

问题


I have tried this test, for testing my service:

It has shown this error:

TypeError: done.fail is not a function

test file

 it('should return reasonable json ssss', inject([ProductService, MockBackend], async((service: ProductService, mockBackend: MockBackend) => {
       const mockResponse = {
            data: [
                { id: 0, details: 'All cats are lions' },
                { id: 1, details: 'Video 1' },
                { id: 2, details: 'Video 2' },
                { id: 3, details: 'Video 3' },
            ]
        };
        mockBackend.connections.subscribe(connection => {
            connection.mockRespond(new Response(
                new ResponseOptions({
                    body: [
                        { id: 0, details: 'All cats are lions' },
                        { id: 1, details: 'Video 1' },
                        { id: 2, details: 'Video 2' },
                        { id: 3, details: 'Video 3' },
                    ]
                })));
        });
        service.productsgetall().subscribe((facts) => {
            console.log(facts)
            expect(facts[0].details).toEqual('ffff');
        });
    })));

- My service.ts

public productsgetall(): Observable<Products[]> {
                ...
 return this.http.get(Api.getUrl(Api.URLS.productsgetall), {
      headers: headers
    }).map((response: Response) => {
        let res = response.json();
        if (res.StatusCode === 1) {
          this.auth.logout();
        } else {
          return res.StatusDescription.map(aa => {
            return new Products(aa);
          });
        }
  });
}

Can you tell me what is the problem in my code and how to write good testing? If this testing is not good, please suggest something.

Thanks.

Edit, my final code. The error:

TypeError: done.fail is not a function

it('should return reasonable json ssss', (done) => {
    inject([ProductService, MockBackend], async((service: ProductService, mockBackend: MockBackend) => {

        const mockResponse = {
            data: [
                { alarmnumber: 0, alarmdesc: 'All cats are lions' },
                { alarmnumber: 1, alarmdesc: 'Video 1' },
                { alarmnumber: 2, alarmdesc: 'Video 2' },
                { alarmnumber: 3, alarmdesc: 'Video 3' },
            ]
        };

        mockBackend.connections.subscribe(connection => {
            connection.mockRespond(new Response(
                new ResponseOptions({
                    body: [
                        { alarmnumber: 0, alarmdesc: 'All cats are lions' },
                        { alarmnumber: 1, alarmdesc: 'Video 1' },
                        { alarmnumber: 2, alarmdesc: 'Video 2' },
                        { alarmnumber: 3, alarmdesc: 'Video 3' },
                    ]
                })));
        });

        service.productsgetall().subscribe(facts=> {
            console.log(facts);
            console.log(facts[0]);
           // expect(facts.length).toEqual(300);
            expect(facts[0].alarmdesc).toEqual('ffff');
            done();
        },
        (error) => done.fail());
    }))();
});

image error


回答1:


Just ran into a similar situation myself in trying to test a simple Angular 6 service that requires http. Not sure what the underlying issue was, but I suspect it has something to do with using async in combination with inject. When I refactored the test to no longer use inject, this error went away.

Note in recent versions of Angular if you are using the new HttpClient, then the 'MockBackend' you are using above has been replaced by HttpTestingController, see an interesting intro to the new httpClient (including testing) on medium.com here.

Given your code above, the refactoring would look something like the following. Obviously I don't have your original service details to test with. :)

import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
describe('ProductService', () => {
    let httpMock: HttpTestingController;
    let service: ProductService;  
    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [HttpClientTestingModule],
            providers: [ProductService]
        });
        httpMock = TestBed.get(HttpTestingController);
        service = TestBed.get(ProductService);
    });
    it('should return reasonable json ssss', async(() => {
        const mockResponse = {
            data: [
                { alarmnumber: 0, alarmdesc: 'All cats are lions' },
                { alarmnumber: 1, alarmdesc: 'Video 1' },
                { alarmnumber: 2, alarmdesc: 'Video 2' },
                { alarmnumber: 3, alarmdesc: 'Video 3' },
            ]
        };
        service.productsgetall().subscribe(facts=> {
            console.log(facts);
            console.log(facts[0]);
            // expect(facts.length).toEqual(300);
            expect(facts[0].alarmdesc).toEqual('ffff');
        });
        let req = httpMock.expectOne('/your/test/url'); // <-- details not provided in your question
        expect(req.request.responseType).toEqual('json');
        req.flush(mockResponse); // send mockResponse back into the subscribe above
    }));
});



回答2:


You have an async test case there, you have to use the done parameter like this:

it('should return reasonable json ssss', (done) => {

  inject([ProductService, MockBackend], async((service: ProductService, mockBackend: MockBackend) => {
    // your implementation

    service.productsgetall().subscribe((facts) => {
      console.log(facts)
      expect(facts[0].details).toEqual('ffff');

      done(); // <-- this will finish the test
    },
    (error) => done.fail());
  }))(); // <-- important, inject itself returns a function which needs to be called

}); 


来源:https://stackoverflow.com/questions/50619893/testing-service-typeerror-done-fail-is-not-a-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!