Аурелия вводит ложную зависимость

У меня есть этот компонент aurelia для отображения канала для пользователя, который зависит от пользовательского класса обслуживания API под названием Api для получения канала. В классе Api есть функция get(), которая, в свою очередь, использует HttpClient для извлечения данных.

Пытаясь протестировать компонент, я хочу смоделировать класс обслуживания, в частности, функцию get, чтобы вернуть подходящие тестовые данные и внедрить этот макет в компонент через DI-контейнер aurelia. Часть DI, с которой у меня проблемы.

Вот соответствующая часть файла JS компонента

import {bindable, inject} from 'aurelia-framework';
import {Api} from 'services/api';

@inject(Api)
export class Feed {
  events = null;

  constructor(api) {
    console.info('feed.js constructor, api:', api)
    this.api = api;
  }

И соответствующий код из моего теста

  beforeEach(done => {
    ...
    let mockApi = new Api();
    spyOn(mockApi, 'get').and.returnValue(mockGetResponse);

    const customConfig = (aurelia) => {
      let conf = aurelia.use.standardConfiguration().instance("Api", mockApi);
      console.info('Registering Api:', conf.container.get("Api"));
      return conf;
    }

    const ct = new ComponentTester();
    ct.configure = customConfig;

    sut = ct.withResources('activityfeed/feed');
    sut.inView('<feed username.bind="username"></feed>')
        .boundTo({username: TEST_USER});

    sut.create(bootstrap).then(() => {
      done();
    });
  });

Этот код на самом деле работает так, как я задумал, насколько я могу судить. При создании компонента вызывается моя функция customConfig, и экземпляр mockApi регистрируется на консоли.

Однако позже в процессе начальной загрузки конструктор компонента все еще получает экземпляр фактического класса обслуживания Api вместо моего ложного экземпляра, который был зарегистрирован в контейнере.

Последние пару часов я потратил, пытаясь найти какую-либо документацию или примеры, чтобы делать подобные вещи без успеха, поэтому, если кто-нибудь сможет помочь, я буду очень признателен.

Или, если есть / есть альтернативные способы для достижения этой цели, которые будут работать так же хорошо.

2 ответа

Решение

При тестировании стандартного компонента, который состоит как из вида, так и из модели вида, используя пакет тестирования aurelia, я обнаружил, что более чистый подход мог бы позволить Aurelia создавать как представление, так и модель представления, и использовать фиктивные классы для всего представления. модельные зависимости.

export class MockApi {
  response = undefined;

  get() { return Promise.resolve(this.response) }
}

describe("the feed component", () => {
  let component;
  let api = new MockApi();

  beforeEach(() => {
    api.response = null;

    component = StageComponent
      .withResources("feed/feed")
      .inView("<feed></feed>");

    component.bootstrap(aurelia => {
      aurelia.use
        .standardConfiguration();

      aurelia.container.registerInstance(Api, api);
    });
  });

  it("should work", done => {
    api.response = "My response";

    component.create(bootstrap).then(() => {
      const element = document.querySelector("#selector");
      expect(element.innerHTML).toBe("My response, or something");

      done();
    });
  });
});

Этот подход позволяет проверять визуализированный HTML-код, используя класс модели нормального представления, высмеивая зависимости для контроля тестовых данных.

Просто чтобы ответить на мой собственный вопрос, хотя бы частично, если он может быть кому-то полезен.

При использовании фактического конструктора класса Api в качестве ключа вместо строки "Api" макет кажется правильно введенным.

Т.е.

import {Api} from 'services/api';

...

      let conf = aurelia.use.standardConfiguration().instance(Api, mockApi);

Другие вопросы по тегам