我的代码中只有参数化构造函数,我需要通过它注入。
我想间谍参数化构造函数将模拟对象注入我的junit的依赖项。
public RegDao(){
//original object instantiation here
Notification ....
EntryService .....
}
public RegDao(Notification notification , EntryService entry) {
// initialize here
}
we have something like below :
RegDao dao = Mockito.spy(RegDao.class);
但是我们有什么东西可以在构造函数中注入模拟对象并窥探它吗?
答案 0 :(得分:10)
你可以通过在junit中使用参数化构造函数实例化主类,然后从中创建一个间谍来实现。
假设您的主要班级是 2018-05-16 08:17:52.334189 DBG:FsLonSource.cpp L01079SQ00011ET 5.334189 CFsLonSource::SubmitCommand(AddressType:Local NI, Mode:0, Selector:0)
2018-05-16 08:17:52.334449 DBG:NodetalkLONInterface.c L01862SQ00012ET 5.334449 AdapterSetAddress(DomainId:, SubnetId:1, NodeId:1)
2018-05-16 08:17:52.334807 DBG:NodetalkLONInterface.c L01522SQ00013ET 5.334807 AdapterSetAddressInternal(DomainId:, SubnetId:1, NodeId:1)
2018-05-16 08:17:52.335413 DBG:NodetalkLONInterface.c L01021SQ00014ET 5.335413 NodeSetAddress(ServiceType: ACKD): ok
2018-05-16 08:17:52.335603 DBG:NodetalkLONInterface.c L01055SQ00015ET 5.335603 NodeSetModeState()
2018-05-16 08:17:52.335783 DBG:NodetalkLONInterface.c L01064SQ00016ET 5.335783 ServiceType: UNACKD
2018-05-16 08:17:52.335966 DBG:NodetalkLONInterface.c L01065SQ00017ET 5.335966 NewMode: ?
2018-05-16 08:17:52.336124 DBG:NodetalkLONInterface.c L01071SQ00018ET 5.336124 NewState: Configured, Online
2018-05-16 08:17:52.339081 DBG:FsLonDispatch.cpp L00342SQ00019ET 5.339081 CFsLonDispatch::ExecRequest(): S_OK
2018-05-16 08:17:52.433098 DBG:FsLonDispatch.cpp L00181SQ00020ET 5.433098 CFsLonDispatch::ExecRequest(request:"<UpdateRest xmln", lTimeout:0, destination:"", correlationId:"")
2018-05-16 08:17:52.436138 DBG:FsLonDispatch.cpp L00250SQ00021ET 5.436138 strCCommand: UpdateRest
2018-05-16 08:17:52.436431 DBG:FsLonDispatch.cpp L00342SQ00022ET 5.436431 CFsLonDispatch::ExecRequest(): S_OK
2018-05-16 08:17:52.437184 DBG:FsLonDispatch.cpp L00181SQ00023ET 5.437184 CFsLonDispatch::ExecRequest(request:"<UpdateRest xmln", lTimeout:0, destination:"", correlationId:"")
2018-05-16 08:17:52.439981 DBG:FsLonDispatch.cpp L00250SQ00024ET 5.439981 strCCommand: UpdateRest
2018-05-16 08:17:52.440331 DBG:FsLonDispatch.cpp L00342SQ00025ET 5.440331 CFsLonDispatch::ExecRequest(): S_OK
2018-05-16 08:17:52.440705 DBG:FsLonDispatch.cpp L00181SQ00026ET 5.440705 CFsLonDispatch::ExecRequest(request:"<UpdateRest xmln", lTimeout:0, destination:"", correlationId:"")
2018-05-16 08:17:52.443586 DBG:FsLonDispatch.cpp L00250SQ00027ET 5.443586 strCCommand: UpdateRest
2018-05-16 08:17:52.443792 DBG:FsLonDispatch.cpp L00342SQ00028ET 5.443792 CFsLonDispatch::ExecRequest(): S_OK
2018-05-16 08:17:52.951870 DBG:NodetalkLONInterface.c L01108SQ00029ET 5.951870 ServiceType: REQUEST
2018-05-16 08:17:52.955944 DBG:NodetalkLONInterface.c L01152SQ00030ET 5.955944 NodeSetModeState(): ok
2018-05-16 08:17:52.956289 DBG:NodetalkLONInterface.c L01555SQ00031ET 5.956289 AdapterSetAddressInternal(): ok
2018-05-16 08:17:52.956655 DBG:NodetalkLONInterface.c L01597SQ00032ET 5.956655 AdapterSetRcvTimer(ServiceType: REQUEST, AddressType: LOCAL)
2018-05-16 08:17:52.966897 DBG:NodetalkLONInterface.c L01625SQ00033ET 5.966897 AdapterSetRcvTimer(): ok
2018-05-16 08:17:52.967216 DBG:NodetalkLONInterface.c L01878SQ00034ET 5.967216 AdapterSetAddress(): ok
2018-05-16 08:17:52.967531 DBG:FsLonSource.cpp L01174SQ00035ET 5.967531 CFsLonSource::SubmitCommand(): ok
。 A
和B
是其依赖项的位置
C
然后你可以使用你的参数化类来编写junit,如下所示
public class A {
private B b;
private C c;
public A(B b,C c)
{
this.b=b;
this.c=c;
}
void method() {
System.out.println("A's method called");
b.method();
c.method();
System.out.println(method2());
}
protected int method2() {
return 10;
}
}
测试类的输出
@RunWith(MockitoJUnitRunner.class)
public class ATest {
A a;
@Mock
B b;
@Mock
C c;
@Test
public void test() {
a=new A(b, c);
A spyA=Mockito.spy(a);
doReturn(20).when(spyA).method2();
spyA.method();
}
}
A's method called
20
和B
是使用参数化构造函数在类C
中注入的模拟对象。A
的{{1}} spy
。A
中受保护方法spyA
的返回值来检查spy
是否确实有效,如果method2
不是A
的实际spyA
。答案 1 :(得分:0)
听起来您可能错过了依赖注入解决方案。 Mockito非常适合与你的DI一起注射嘲笑。例如,您可以使用CDI,为Notification
和EntryService
成员注释@Inject
,在测试中为两者声明@Mock
,然后让Mockito将这些内容注入您的RegDao
进行测试。
这是我认为你试图运行的测试的工作模型:
import static org.junit.Assert.assertEquals;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class MockitoSpyInjection {
static class Notification { }
static class EntryService { }
static class RegDao {
@Inject
Notification foo;
@Inject
EntryService bar;
public RegDao() {
}
public RegDao(Notification foo, EntryService bar) {
this.foo = foo;
this.bar = bar;
}
public Notification getFoo() {
return foo;
}
public EntryService getBar() {
return bar;
}
}
@Mock
Notification foo;
@Mock
EntryService bar;
@Spy
@InjectMocks
RegDao dao;
@Test
public void test() {
assertEquals(foo, dao.getFoo());
assertEquals(bar, dao.getBar());
}
}