0

Надеюсь, что фрагментов кода примера достаточно, чтобы перестроить мою проблему.mock constructor and super injected field with PowerMockito

У меня есть класс TreeWalker и подкласс ABCTreeWalker extends TreeWalker. Я работаю с впрыском пружинной зависимости и в TreeWalker У меня есть зависимость Helper helper;, которая защищена и, следовательно, также доступна в ABCTreeWalker. Все зависимости, такие как helper, вводятся в поле с пружинами @Autowired, поэтому нет сеттера.

public class TreeWalker { 

    @Autowired 
    protected Helper helper; 
} 


public class ABCTreeWalker extends TreeWalker { 

    @Override 
    public void doSomething() { 
     String something = helper.getSomething(); 
     InstanceModel instanceModel = new InstanceModel(something); 
     // ... more stuff ... 
    } 
} 

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

  • впрыснуть издеваться из helper в мой ABCTreeWalker класс под тест
  • высмеивать вызов конструктора

Мой тест работает с @RunWith(PowerMockRunner.class), что позволяет вводить helper с @InjectMocks и @Mock Аннотации. НО: Чтобы подготовиться к конструкторскому макету, мне нужно подготовить класс под тестом, который равен ABCTreeWalker с аннотацией @PrepareForTest(ABCTreeWalker.class). И если я это сделаю, инъекция больше не случится (я думаю, потому что это произошло из суперкласса).

@RunWith(PowerMockRunner.class) 
@PrepareForTest(ABCTreeWalker.class) 
public class ABCTreeWalkerTest { 

    @InjectMocks 
    private ABCTreeWalker abcTreeWalker; 

    @Mock 
    private Helper helper; 

    @Test 
    public void testVisitGui() throws Exception { 
     // ... more stuff ... 
     when(helper.getSomething()).thenReturn("test"); 
     InstanceModel instanceModel = mock(InstanceModel.class); 
     PowerMockito.whenNew(InstanceModel.class) 
      .withArguments("test") 
      .thenReturn(instanceModel); 
     // ... more stuff ... 

     abcTreeWalker.doSomething(); // execute 

     // assertions etc. 
} 

Так что теперь я могу сделать?

  • Я мог бы привнести helper в моих ABCTreeWalker, но это является излишним
  • я, вероятно, мог бы создать сеттер, но это только для теста
  • я не могу rmeove Powermock из конструктора насмешливого

У вас есть предложения?

+0

Что вы получаете без @PrepareForTest (ABCTreeWalker.class) – Guna

+0

Тогда инъекция работает, но я больше не могу издеваться над вызовом конструктора. – BAER

ответ

0

Вы думаете о @Autowired конструктору

public class TreeWalker { 
protected Helper helper; 

@Autowired 
public TreeWalker(Helper helper){ 
    this.helper = helper; 
} 

} А затем вызвать супер() в конструкторе ребенка?

+0

Я могу только изменить дочерний класс, суперкласс происходит из-за maven. Я работаю над «обычным решением» «стандартного продукта», где я не могу изменить последнее. – BAER

+0

Извините, я поставил неправильный класс. Конструктор может быть для класса ABCTreeWalker. 'открытый класс ABCTreeWalker { @Autowired общественный ABCTreeWalker (помощник помощника) { this.helper = helper; } ' –