问题
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