我正在尝试为通常由Spring管理的某些代码编写JUnit测试。

假设我有这个:

@Configurable
public class A {
  @Autowired MyService service;

  public void callA() { service.doServiceThings(); }
}


我可以使用Mockito和PowerMock为此类编写测试,如下所示:

@RunWith(PowerMockRunner.class)
public class ATest {
  @Spy MyService service = new MyService();

  @Before void initMocks() { MockitoAnnotations.initMocks(this); }

  @Test void test() {
    @InjectMocks A a = new A(); // injects service into A
    a.callA();
    //assert things
  }
}


但是现在我遇到了其他一些类构造A实例的情况:

public class B {
  public void doSomething() {
    A a = new A(); // service is injected by Spring
    a.callA();
  }
}


如何使服务注入到在B方法中创建的A实例中?

@RunWith(PowerMockRunner.class)
public class BTest {
  @Spy MyService service = new MyService();

  @Before void initMocks() { MockitoAnnotations.initMocks(this); }

  @Test testDoSomething() {
     B b = new B();
     // is there a way to cause service to be injected when the method calls new A()?
     b.doSomething();
     // assert things
  }
}

最佳答案

场注入确实很烂,但是您仍然可以做一件事来轻松地将A实例化(或者也许我误解了)。使B具有通过构造函数注入的AFactory。

public class B {
    private final AFactory aFactory;
    public B(AFactory aFactory) {
        this.aFactory=aFactory;
    }
    public void doSomething() {
    A a = aFactory.getA();
    a.callA();
    }
}


然后,您可以创建aFactory的Mock,然后通过构造函数将其注入B。

07-24 09:18