#angular #unit-testing #jasmine
#angular #модульное тестирование #жасмин
Вопрос:
Я создал UserService, который сохраняет пользователя в базе данных. У меня также есть служба, которая предварительно настраивает конечные точки для локальных, qa, uat и prod, называемых UrlService. Этот класс возвращает в обещании URL-адреса с использованием APP_INITIALIZER, который работает нормально. Похоже, конфигурация в URL-адресах папки ресурсов.json мешает тестам. Когда я добавил консоль.войдите в метод matches, он выводит путь в /asset/urls.json. Я не понимаю, как это может мешать моим тестам. Я озадачен, что это может иметь какое-либо отношение к моим тестам, но любая информация поможет.
Когда я запускаю свои тесты, он завершается ошибкой:
Error: Expected one matching request for criteria "Match by function: ", found 2 requests. I print out the URL and it matches what gets printed in the service and it matches the one in the test.
Как URL-адреса могут не совпадать? Я полностью смущен этим?
Кто-нибудь имеет представление о том, как это может быть?
export class UserDetail{
name: string;
department: string;
userId: string;
}
saveUser(
user: UserDetail,
url: string
): Observable<UserDetail> {
return this.http
.post<UserDetail>(
url,
user,
this.httpOptions
)
.pipe(
tap(
(resp: UserDetail) =>
console.log(`New User ${user}`),
(error) => {
console.log('Received an error', error);
}
)
);
console.log('URL passed is ', url);
}
it("Create User", fakeAsync(() => {
user = {
name: "Ranger",
department: "Merch",
userId: "1222222",
};
let response = null;
const URL = urlService.getConfig().userLocal;
userService.saveUser(user, URL).subscribe(
(expectedResponse) => {
response = expectedResponse;
},
(error: any) => {}
);
const req = httpMock.expectOne((request) => {
console.log("URL is: ", request.url);
return true;
});
const requestWrapper = httpMock.expectOne({
url: URL,
});
requestWrapper.flush(user);
tick();
expect(requestWrapper.request).toBeTruthy();
expect(requestWrapper.request.method).toEqual("POST");
expect(response.request).toBeTruthy();
}));
Ответ №1:
Проблема в том, что httpMock
он запускается дважды, поэтому, когда вы expectOne
терпите неудачу и выдаете сообщение об ошибке, которое вы показали : ... found 2 requests.
.
Чтобы решить эту проблему, вы можете определить ожидаемый запрос, что-то похожее на:
httpMock.expectOne((request) =>
return request.method === 'POST' amp;amp; request.url === URL;
);
Редактировать:
Позвольте мне далее объяснить, что если вы сделаете два вызова с помощью HttpClient и в вашем тесте expectOne, ваш тест завершится ошибкой с сообщением об ошибке, которое вы получаете.
Смотрите Пример с этой службой:
export class DataServiceService {
constructor(private httpClient: HttpClient) { }
testSingleCall() {
return this.httpClient.get('/data').subscribe();
}
testDoubleCalls() {
this.httpClient.get('/data').subscribe();
this.httpClient.get('/data').subscribe();
}
}
и вот тестовый файл:
it('should test httpmock', () => {
service.testSingleCall();
// If no request with that URL was made, or if multiple requests match, expectOne() would throw.
httpMock.expectOne("/data");
});
it('should test httpmock multiple calls', () => {
service.testDoubleCalls();
const requests = httpMock.match("/data");
expect(requests.length).toEqual(2);
});
если вы запустите httpMock.expectOne("/data")
testDoubleCalls()
тест, произойдет сбой, потому что служба выполняет два вызова, и тест ожидает, что будет только один вызов.
Комментарии:
1. Привет, ты имеешь в виду этот вызов? const req = httpMock.expectOne((request) => { console.log(«URL is: «, request.url); возвращает true; });, Перед добавлением этого вызова произошел сбой
2. это либо этот, либо другой вызов (const requestWrapper = httpMock.expectOne({ url: URL, }); — оба ожидают один вызов (expectOne), но получают два вызова — те же два вызова
3. Спасибо, позвольте мне разобраться в этом.
4. @BreenDeen — я добавил более подробное объяснение, надеюсь, это поможет
5. Огромное спасибо, очень признателен!!