Сбой HttpTestingController из-за несоответствия критериям

#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. Огромное спасибо, очень признателен!!