2016-04-22 3 views
0

У меня есть услуга 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 (ну, методы на самом деле не являются частными, но, по крайней мере, они находятся в другом объеме, а код контроллера выглядит довольно неплохо.

+0

Почему вы хотите протестировать частные методы? Вы должны тестировать полученное состояние/возвращаемое значение общедоступных методов, то есть _behaviour_ компонента, а не его внутреннюю структуру. – Rhumborl

+0

Я согласен с @Rhumborl, но возможным решением является определение службы с рецептом поставщика, проверка некоторых свойств инициализации как «testContext», и если true, вы можете публиковать частные методы в области $ – fantarama

+0

Ну, это одна из точек зрения. Это хорошая причина. Но это единичные тесты. Unit = функции. Для тестирования поведения мы должны использовать интеграционные тесты, а не единицы.Фактически, когда я создал некоторую услугу полгода назад, я сделал частные методы, и мои модульные тесты действительно проверяют поведение компонентов. Теперь я сделал некоторые незначительные исправления, и мне нужно изменить рефакторинг всех модульных тестов (~ 50). Ну да. Поведение изменилось, поэтому повод изменить единицы: издевательства и тесты. Но все эти тесты сложно поддерживать все время. Вот почему у меня есть этот вопрос. –

ответ

0

Прежде всего, вы должны издеваться над всеми зависимостями вашего сервиса с $ обеспечивают:

var privateDep = jasmine.createSpyObj('privateDep', ['get']); 

beforeEach(function() { 
    module('module name', function($provide) { 
    $provive.value('privateDep', privateDep); 
    }); 
}); 

Это позволяет следить за зависимости при тестировании общих методов вашей службы:.

it('test publicFoo', function() { 
    expect(myService.publicFoo()).toEqual(5); 
    expect(privateDep.get).toHaveBeenCalledWith(123); 
}); 

частных методы никогда не будут проверяемым Это не проблема, потому что вся логика частных методов подвергается публичным методам, и вы можете их протестировать.

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

+0

Это не ответ. Я сказал, что мне нужно высмеять все объекты. И это не хорошо, потому что после этого трудно поддерживать единицы. Я должен настроить большие отпечатки для каждого теста. Для каждого. –

Смежные вопросы