2015-09-16 5 views
0

Рассмотрим следующий класс:Как объединить тестовые узлы графа с mockito?

public class Node { 
    private final Collection<Node> mDependants = new ArrayList<>(); 
    private Node mDependency; 

    public void initialize(final Node node) { 
     // complex code that might call registerDependency; 
    } 

    private void registerDependency(final Node node) { 
     mDependency = node; 
     node.registerDependent(this); 
    } 

    private void registerDependent(final Node node) { 
     mDependants.add(node); 
    } 
} 

, а затем модульного тестирования, как:

import static org.mockito.Mockito.mock; 

public class NodeTest { 
    private Node mTarget; 
    private Node mDependent; 

    @Before 
    public void setUp() { 
     mTarget = new Node(); 
     mDependent = mock(Node.class); 
    } 

    @Test 
    public void test() { 
     mTarget.initialize(mDependent); 
    } 
} 

С registerDependent является частным, Mockito не будет на самом деле дразнить его. Поскольку mTarget фактически является реальным экземпляром, когда метод registerDependency выполняется посредством инициализации, он попытается выполнить приватный метод registerDependent на макет. Макет, являющийся макетом, не будет инициализирован, а mDependants на самом деле будет пустым, вызывая NullPointerException на mDependats.add (node).

Каким должен быть правильный способ проверить это? Должен ли я использовать два реальных узла вместо макета? следует ли публиковать методы, чтобы позволить насмехаться над этим методом? Есть ли другой вариант, который мне не хватает? Final Узел узла

+0

Я не вижу никаких проблем с вашим кодом, кроме некоторых объявлений импорта. Я не смог воспроизвести исключение NullPointerException. –

ответ

2

Поскольку это тест для узла, избегайте насмешливого узла, если это вообще возможно. Это позволяет легко проверить, что фальшивая структура работает правильно или что ваша спецификация определена правильно, а не тестирование, если ваша реализация верна.

Я фанат, как JB Nizet положить в his SO answer here: Если вы строите бомбы детонатор, ваши частые испытания должны использовать реальный детонатор и макет бомбу. Исправления должны быть для зависимостей и сотрудников вашей системы, а не самой системы.

Если ваш узел был интерфейсом, и ваша реализация NodeImpl могла принимать любой узел в качестве зависимого, то может иметь смысл использовать макет узла - оба, поскольку вы могли бы передавать узлы с различными реализациями, которые могут даже не существовать тем не менее, и потому, что многие из Mockito's gotchas уходят, когда вы ограничиваете себя насмешливыми интерфейсами. Однако, поскольку Node и его зависимый узел являются одним и тем же конкретным классом и опираются на частные детали реализации, у вас, вероятно, будет гораздо больше успеха в работе с реальными экземплярами.

Кроме того, эти узлы вряд ли будут включать в себя тяжелые уровни обслуживания или другие зависимости, которые поддаются насмешкам, и нет сомнений в том, хорошо ли ведет себя узел: вы можете видеть, что он находится в ваших соседних тестах.

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

+0

Спасибо, ваша аналогия сделала это очень понятным для меня, это имеет смысл. Я сделаю так. – superjugy

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

  • Нет связанных вопросов^_^