У меня есть услуга AngularJS. Пример:Как сделать «частные» методы AngularJS?
module.service('myService', function() {
var privateFoo = function() {
console.log('I am public foo');
},
self = this;
self.publicFoo = function() {
console.log('I am public foo');
};
});
Тестирование этого сервиса:
it('test service', function() {
expect(myService.publicFoo).toBeDefined(); // ok
expect(myService.privateFoo).toBeDefined(); // not defined
});
работает как шарм. Как и ожидалось.
Проблема в том, что я хочу также проверить частные методы. Зачем мне это нужно?
Представьте себе, что privateFoo
использование/изменение какой-либо закрытый объект. У меня есть publicFoo
. Существует звонок privateFoo
в publicFoo
. Я хочу провести тестирование publicFoo
. Для этого мне нужно высмеять все зависимости publicFoo
и все объекты от функций, которые вызываются от publicFoo
i.e. privateFoo
.
Пример такой службы:
module.service('myService', function (privateDep) {
var privateFoo = function() {
privateDep.get('123');
},
self = this;
self.publicFoo = function() {
privateFoo();
return 5;
};
});
Испытание publicFoo:
it('test publicFoo', function() {
expect(myService.publicFoo()).toEqual(5); // fail, privateDep.get trying to get get of undefined
});
Итак, мне нужно издеваться privateDep испытать publciFoo.
На самом деле, я хочу что-то вроде (только, например, он не работает, потому что privateFoo является частным :)):
it('test publicFoo', function() {
spyOn(service, 'privateFoo');
expect(myService.publicFoo()).toEqual(5); // fail, privateDep.get trying to get get of undefined
expect(service.privateFoo).toHaveBeenCalled();
});
Это будет возможно, если я буду делать частные методы общественности, но, например, , с некоторым префиксом, например _
. Примерно так: self._privateFoo
. Префикс _
покажет пользователям API, этот метод является закрытым, и они не должны его использовать.
Как сделать методы действительно частными и проверяемыми в службе AngularJS? Хорошее решение для контроллеров (с $ scope) в this post (ну, методы на самом деле не являются частными, но, по крайней мере, они находятся в другом объеме, а код контроллера выглядит довольно неплохо.
Почему вы хотите протестировать частные методы? Вы должны тестировать полученное состояние/возвращаемое значение общедоступных методов, то есть _behaviour_ компонента, а не его внутреннюю структуру. – Rhumborl
Я согласен с @Rhumborl, но возможным решением является определение службы с рецептом поставщика, проверка некоторых свойств инициализации как «testContext», и если true, вы можете публиковать частные методы в области $ – fantarama
Ну, это одна из точек зрения. Это хорошая причина. Но это единичные тесты. Unit = функции. Для тестирования поведения мы должны использовать интеграционные тесты, а не единицы.Фактически, когда я создал некоторую услугу полгода назад, я сделал частные методы, и мои модульные тесты действительно проверяют поведение компонентов. Теперь я сделал некоторые незначительные исправления, и мне нужно изменить рефакторинг всех модульных тестов (~ 50). Ну да. Поведение изменилось, поэтому повод изменить единицы: издевательства и тесты. Но все эти тесты сложно поддерживать все время. Вот почему у меня есть этот вопрос. –