简体   繁体   English

使用PowerMockito模拟构造器和超级注入字段

[英]mock constructor and super injected field with PowerMockito

I hope the example code snippets are enough to rebuild my problem. 我希望示例代码片段足以重现我的问题。

I Have a class TreeWalker and a sub class ABCTreeWalker extends TreeWalker . 我有一个TreeWalker类和一个ABCTreeWalker extends TreeWalker子类ABCTreeWalker extends TreeWalker I work with Spring Dependency Injection and in the TreeWalker I have a dependency Helper helper; 我使用Spring Dependency Injection,在TreeWalker我有一个依赖Helper helper; which is protected and thus also available in the ABCTreeWalker . 它受保护,因此也可以在ABCTreeWalker All dependencies like this helper are field-injected with Springs @Autowired , so there is no setter. 像该helper这样的所有依赖项都通过Springs @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 ...
    }
}

I need to create a Unit-Test for the ABCTreeWalker class in which I need to do two things: 我需要为ABCTreeWalker类创建一个单元测试,在其中需要做两件事:

  • Inject a mock of the helper into my ABCTreeWalker class under test 将模拟的helper注入到我的ABCTreeWalker类中进行测试
  • mock the constructor call 模拟构造函数调用

My Test runs with the @RunWith(PowerMockRunner.class) which allows to inject the helper with @InjectMocks and @Mock Annotations. 我的测试使用@RunWith(PowerMockRunner.class)运行,它允许使用@InjectMocks@Mock Annotations注入helper @InjectMocks BUT: In order to prepare for the constructor mock I need to prepare the Class under Test which is ABCTreeWalker with the annotation @PrepareForTest(ABCTreeWalker.class) . 但是:为了准备构造函数模拟,我需要准备要测试的类,它是ABCTreeWalker带有注释@PrepareForTest(ABCTreeWalker.class) And if I do this, the injection won't happen anymore (I guess because it came from the super 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.
 }

So what can I do now? 那我现在该怎么办?

  • I could inject the helper in my ABCTreeWalker , but that is redundant 我可以将helper插入ABCTreeWalker ,但这是多余的
  • I probably could create a setter, but that would only for the test 我可能可以创建一个二传手,但这仅用于测试
  • I can't rmeove Powermock because of the constructor mocking 由于构造函数模拟,我无法删除Powermock

Do you guys have suggestions? 你们有建议吗?

Have you think about a @Autowired constructor 您是否考虑过@Autowired构造函数

public class TreeWalker {
protected Helper helper;

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

} And then call the super() in the constructor of the child? 然后在子代的构造函数中调用super()?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM