2015-04-13 2 views
0

У меня есть класс, который содержит кучу методов, я написал модульные тесты для каждого метода. Основным методом в классе является метод encrypt, который принимает сообщение и шифрует его. Я также написал как 5 других методов, которые используются этим методом шифрования, но я не хочу, чтобы пользователь мог вызвать эти методы, я просто хочу использовать их внутри метода шифрования, чтобы выполнить эту работу, но я не хочу, чтобы пользователь делал как @ obj.some_method_that_is_not_encrypt, я хочу сделать только метод encrypt invokable, я знаю, что могу сделать эти методы частными, но тогда мои модульные тесты не удастся. Как мне с этим справиться?Как ограничить пользователей от вызова определенных методов

+1

посмотреть здесь http://stackoverflow.com/questions/267237/whats-the-best-way-to-unit-test-protected-private-methods-in-ruby вы можете использовать отправить чтобы обойти частные. – Doon

+0

@ Да, но разве это не вонючий? –

+2

Определение запаха оставлено как упражнение для читателя :) он открывает совершенно новую банку червей. Но тот факт, что ваши (или ваши классы) пользователи могут делать это и обходить частные средства частным образом, следует рассматривать как предложение в любом случае. Но, увы, у меня нет хорошего ответа. Обычно я тестирую публичные интерфейсы/поведение класса, в отличие от каждой функции, для правильного или неправильного. – Doon

ответ

1

модульных тесты можно использовать Object#send(...) для вызова частных методов:

class Foo 
private 
    def bar 
    "ok" 
    end 
end 

f = Foo.new 
f.bar # => NoMethodError: private method `bar' called... 
f.send(:bar) # => "ok" 

Таким образом, ваш метод «шифровать» может быть только публичной, но он все еще может использовать частные методы, которые не подвергаются воздействию вежливых пользователей вашей библиотеки (они могут, конечно, использовать send также, если они захотят).

Обратите также внимание на то, что особый аспект «частных» методов заключается в том, что они не могут быть вызваны с явным приемником, даже в том же классе. Поэтому вы не могли позвонить self.my_private_method, вместо этого вы должны просто позвонить my_private_method. Например:

class Foo 
    def foo 
    self.bar # => NoMethodError: private method `bar' called... 
    bar # => "ok" 
    end 
private 
    def bar; "ok"; end 
end 
Смежные вопросы