Аурелия вводит ложную зависимость
У меня есть этот компонент 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);