Какова цель протестировать?
в большинстве ответов до сих пор говорится, что закрытые методы являются деталями реализации, которые не делают (или по крайней мере не был должен), вопрос, пока открытый интерфейс хорошо протестирован и работа. Это абсолютно корректно , если Ваша единственная цель для тестирования состоит в том, чтобы гарантировать, что открытый интерфейс работает .
Лично, мое основное использование для тестов кода должно гарантировать, чтобы будущие изменения кода не вызывали проблемы и помочь моим усилиям по отладке, если они делают. Я нахожу что, тестируя закрытые методы так же полностью как открытый интерфейс (если не больше!) furthers та цель.
Рассмотрите: у Вас есть открытый метод A, который называет закрытый метод B. A и B, оба используют метод C. C изменяется (возможно, Вами, возможно, поставщиком), заставляя начинать проваливать его тесты. Не было бы полезно иметь тесты для B также, даже при том, что это является частным, так, чтобы Вы знали, находится ли проблема в употреблении A C, использовании B C или обоих?
закрытые методы Тестирования также увеличивают стоимость в случаях, где тестовое покрытие открытого интерфейса является неполным. В то время как это - ситуация, мы обычно хотим избежать, поблочное тестирование эффективности зависит и от тестов, находящих ошибки и от связанной разработки и затрат на обслуживание тех тестов. В некоторых случаях преимущества 100%-го тестового покрытия могут быть оценены недостаточные для гарантирования затрат на те тесты, произведя разрывы в тестовом покрытии открытого интерфейса. В таких случаях хорошо предназначенный тест закрытого метода может быть очень эффективным дополнением к кодовой базе.
traverse(Liste) ->
traverse(Liste, []).
traverse([], Acc) ->
Acc;
traverse([1|_], Acc) ->
Acc;
traverse([H|T], Acc) ->
% do something useful here maybe?
traverse(T, Acc).
Конечно, это очень примерный пример.
Другой способ сделать это - использовать throw
и catch
:
catch lists:foreach(
fun(1) ->
throw(found_one);
(X) ->
io:format("~p~n", [X])
end,
[2, 4, 5, 1, 2, 5]).
При запуске в оболочке это выводит:
2
4
5
found_one
EDIT : По многочисленным просьбам, более точная версия, улавливающая только то, что вы хотите поймать:
try lists:foreach(
fun(1) ->
throw(found_one);
(X) ->
io:format("~p~n", [X])
end,
[2, 4, 5, 1, 2, 5])
catch
throw:found_one ->
found_one
end.
В модуле lists есть много хороших функций:
lists:foreach(fun(E) -> do_something(E) end,
lists:takewhile(fun(E) -> E =/= 1 end, List)).
или более эффективные, но менее красивые
lists:takewhile(fun(1) -> false;
(E) -> do_something(E), true
end, List)