Angular - используйте Jasmine, чтобы шпионить за связанными методами в HttpClient - PullRequest
0 голосов
/ 26 октября 2018

У меня есть ситуация, когда мне нужно шпионить за методом, который вызывается после вызова другого метода.

Вот тестируемый класс / метод:

@Injectable()
export class SomeService {

  constructor(private customHttpClient: CustomHttpClient) {
  }

    updateSomethingCool(signerVO: SignerVO): Observable<SignerVO> {

    // ...

    return this.customHttpClient.withCustomOverrides(new CustomErrorHandlerHttpInterceptorOverride({ passthroughStatusCodes: [BAD_REQUEST, BAD_GATEWAY] }))
        .put<SignerVO>(`/my/url/goes/here`, signerVO);
    }
}

Этот класс использует CustomHttpClient, который выглядит следующим образом:

    @Injectable()
    export class CustomHttpClient extends HttpClient {
        private interceptors: HttpInterceptor[] | null = null;

        constructor(private injector: Injector,
            originalHandler: HttpHandler, private originalBackend: HttpBackend) {
            super(originalHandler);
        }

        public withCustomOverrides(...overrides: CustomHttpInterceptorOverride[]): HttpClient {

            // do very customizable things here

            return new CustomDelegatingHttpClient(
                new CustomHttpInterceptingHandler(this.originalBackend, this.interceptors, overrides));
        }
    }

    export class CustomDelegatingHttpClient extends HttpClient {
        constructor(private delegate: HttpHandler) {
            super(delegate);
        }
}

Вот моя попытка модульного тестирования, что метод put действительно был вызван, поэтому мне нужно шпионить за put методом:

describe(SomeService.name, () => {
let service: SomeService;
let customHttpClient: CustomHttpClient;

let emptySignerVO: SignerVO = new SignerVO();

beforeEach(() => {
    customHttpClient= <CustomHttpClient>{};
    customHttpClient.put = () => null;
    customHttpClient.withCustomOverrides = () => null;

    service = new SomeService(customHttpClient);
});

describe('updateSomethingCool', () => {

    it('calls put', () => {
        spyOn(customHttpClient, 'put').and.stub();

        service.updateSomethingCool(emptySignerVO);

        expect(customHttpClient.put).toHaveBeenCalled();
    });
});

Теперь ясно, когда я запускаю это, я получаю это сообщение об ошибке:

TypeError: Cannot read property 'put' of null

Однако я не знаю точно, как определить методы put или withCustomOverrides в части beforeEach теста.

Обратите внимание, что CustomHttpClient - это просто настраиваемый класс-оболочка для HttpClient от Angular, который предоставляет некоторые более подробные функции.

Спасибо за вашу помощь!

Ответы [ 3 ]

0 голосов
/ 27 октября 2018

Используете ли вы инъекцию угловых зависимостей для ввода HttpClient в CustomHttpClient?При тестировании сервисов, которые зависят от HttpClient, вы можете использовать HttpTestingController, для тестирования сервисного блока это может выглядеть следующим образом:

it(`should get a new data instance of type T`, 
  async(inject([TestDataService, HttpTestingController],
  (service: TestDataService, backend: HttpTestingController) => {
    // ... tests here
  })
));
0 голосов
/ 30 октября 2018

Ну, в конце концов, я не так уж и далек. Фактический тестовый код был в порядке; метод beforeEach() необходимо обновить следующим образом:

beforeEach(() => {
    customHttpClient = <CustomHttpClient>{};
    customHttpClient.put = () => null;
    customHttpClient.withCustomOverrides = () => customHttpClient;

    service = new SomeService(customHttpClient);
});

Мне просто нужно было присвоить объект customHttpClient методу .withCustomOverides.

Что, если вы посмотрите на поток цепочек методов в реальном вызове, действительно имеет смысл.

0 голосов
/ 26 октября 2018

Я думаю, вы должны ввести httpClient;

beforeEach((http: HttpClient) => {
  httpClient = http;
  httpClient.put = () => null;
  httpClient.withCustomOverrides = () => null;
  service = new SomeService(log, httpClient);});
...