mockito 调用真正的方法
mockito Call real methods
我有这个测试:
但是方法 checkIfHold 也被嘲笑
@RunWith(MockitoJUnitRunner.class)
public class FrontSecurityServiceTest {
@Mock
private FrontSecurityService frontSecurityService
= mock( FrontSecurityService.class, withSettings().defaultAnswer(CALLS_REAL_METHODS));
@Test
public void test1() {
when(frontSecurityService.getLoggedInUserId()).thenReturn("000");
frontSecurityService.checkIfHold(9L);
}
}
我也试过
@Mock
PerService perService;
@Spy
private FrontSecurityService frontSecurityService = new FrontOfficeSecurityService(perService);
但不是模拟方法 getLoggedInUserId()
,getLoggedInUserId 是 public,非静态和非最终的。
我也试过了,确实可以,但是里面调用了MenService checkIfHold为null
@RunWith(SpringJUnit4ClassRunner.class)
public class FrontSecurityServiceTest {
@Mock
MenService menService;
@Mock
FrontSecurityService frontSecurityService;
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Test
public void test1() {
MenReturn menReturn1 = MenReturn.builder().build();
when(menService.getMen(anyString(), anyLong())).thenReturn(Arrays.asList(menReturn1));
when(frontSecurityService.checkIfHold(anyLong())).thenCallRealMethod();
when(frontSecurityService.getLoggedInUserId()).thenReturn("000");
frontSecurityService.checkIfHold(9L);
}
}
我想 @Spy
就是您要找的。尽管如此,测试 FrontSecurityService
并同时模拟它对我来说似乎很奇怪。
请尝试以下操作:
@RunWith(MockitoJUnitRunner.class)
public class FrontSecurityServiceTest {
@Spy
private FrontSecurityService frontSecurityService;
@Test
public void test1() {
when(frontSecurityService.getLoggedInUserId()).thenReturn("000");
frontSecurityService.checkIfHold(9L);
}
}
理想情况下,对于 FrontSecurityServiceTest,您不应该模拟 FrontSecurityService。那是你的被测系统,你不想测试你的模拟,你想测试你正在测试的系统。
正如我在 上的其他回答中一样,如果您使用 CALLS_REAL_METHODS
进行了模拟,那么您将与您的系统 (FrontSecurityService) 进行交互,但它没有 运行 任何构造函数并且尚未初始化任何字段。 FrontSecurityService 极不可能像那样按预期工作。
与 , @Spy
is what you're looking for. As in the docs, you don't need to call the constructor explicitly, but only because @Spy
is documented to do so for you 相同。如果您没有零参数构造函数,@Spy
将要求您调用构造函数,因此调用构造函数并不是一个坏习惯——尤其是当您使用依赖注入框架或某些构造函数稍后可能获得参数的其他上下文。您的 IDE 不理解 Mockito,并且不会检测到正在以反射方式调用构造函数。
一旦你有了 @Spy
,事情应该会如你所愿——前提是 getLoggedInUserId
是 public
、非 static
和非 final
.
我认为第一个问题是您在使用 @Mock
注释的同时还使用了 Mockito.mock(...)
。
你可以模拟一个对象,然后告诉 Mockito 哪些方法应该执行真正的实现
尝试以下操作:
@RunWith(MockitoJUnitRunner.class)
public class FrontSecurityServiceTest {
private FrontSecurityService frontSecurityService = Mockito.mock(FrontSecurityService.class);
@Test
public void test1() {
when(frontSecurityService.getLoggedInUserId()).thenReturn("000");
when(frontSecurityService.checkIfHold(Mockito.any())).thenCallRealMethod();
frontSecurityService.checkIfHold(9L);
}
}
如果 checkIfHold
方法 returns 无效,那么您必须执行如下操作:
Mockito.doCallRealMethod().when(frontSecurityService).checkIfHold(Mockito.any());
我有这个测试: 但是方法 checkIfHold 也被嘲笑
@RunWith(MockitoJUnitRunner.class)
public class FrontSecurityServiceTest {
@Mock
private FrontSecurityService frontSecurityService
= mock( FrontSecurityService.class, withSettings().defaultAnswer(CALLS_REAL_METHODS));
@Test
public void test1() {
when(frontSecurityService.getLoggedInUserId()).thenReturn("000");
frontSecurityService.checkIfHold(9L);
}
}
我也试过
@Mock
PerService perService;
@Spy
private FrontSecurityService frontSecurityService = new FrontOfficeSecurityService(perService);
但不是模拟方法 getLoggedInUserId()
,getLoggedInUserId 是 public,非静态和非最终的。
我也试过了,确实可以,但是里面调用了MenService checkIfHold为null
@RunWith(SpringJUnit4ClassRunner.class)
public class FrontSecurityServiceTest {
@Mock
MenService menService;
@Mock
FrontSecurityService frontSecurityService;
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Test
public void test1() {
MenReturn menReturn1 = MenReturn.builder().build();
when(menService.getMen(anyString(), anyLong())).thenReturn(Arrays.asList(menReturn1));
when(frontSecurityService.checkIfHold(anyLong())).thenCallRealMethod();
when(frontSecurityService.getLoggedInUserId()).thenReturn("000");
frontSecurityService.checkIfHold(9L);
}
}
我想 @Spy
就是您要找的。尽管如此,测试 FrontSecurityService
并同时模拟它对我来说似乎很奇怪。
请尝试以下操作:
@RunWith(MockitoJUnitRunner.class)
public class FrontSecurityServiceTest {
@Spy
private FrontSecurityService frontSecurityService;
@Test
public void test1() {
when(frontSecurityService.getLoggedInUserId()).thenReturn("000");
frontSecurityService.checkIfHold(9L);
}
}
理想情况下,对于 FrontSecurityServiceTest,您不应该模拟 FrontSecurityService。那是你的被测系统,你不想测试你的模拟,你想测试你正在测试的系统。
正如我在 CALLS_REAL_METHODS
进行了模拟,那么您将与您的系统 (FrontSecurityService) 进行交互,但它没有 运行 任何构造函数并且尚未初始化任何字段。 FrontSecurityService 极不可能像那样按预期工作。
与 @Spy
is what you're looking for. As in the docs, you don't need to call the constructor explicitly, but only because @Spy
is documented to do so for you 相同。如果您没有零参数构造函数,@Spy
将要求您调用构造函数,因此调用构造函数并不是一个坏习惯——尤其是当您使用依赖注入框架或某些构造函数稍后可能获得参数的其他上下文。您的 IDE 不理解 Mockito,并且不会检测到正在以反射方式调用构造函数。
一旦你有了 @Spy
,事情应该会如你所愿——前提是 getLoggedInUserId
是 public
、非 static
和非 final
.
我认为第一个问题是您在使用 @Mock
注释的同时还使用了 Mockito.mock(...)
。
你可以模拟一个对象,然后告诉 Mockito 哪些方法应该执行真正的实现
尝试以下操作:
@RunWith(MockitoJUnitRunner.class)
public class FrontSecurityServiceTest {
private FrontSecurityService frontSecurityService = Mockito.mock(FrontSecurityService.class);
@Test
public void test1() {
when(frontSecurityService.getLoggedInUserId()).thenReturn("000");
when(frontSecurityService.checkIfHold(Mockito.any())).thenCallRealMethod();
frontSecurityService.checkIfHold(9L);
}
}
如果 checkIfHold
方法 returns 无效,那么您必须执行如下操作:
Mockito.doCallRealMethod().when(frontSecurityService).checkIfHold(Mockito.any());