我正在尝试为一些通常由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通过构造函数注入一个工厂。
public class B {
private final AFactory aFactory;
public B(AFactory aFactory) {
this.aFactory=aFactory;
}
public void doSomething() {
A a = aFactory.getA();
a.callA();
}
}
然后你可以创建一个Mock of aFactory,并通过构造函数把它注入到B。