【发布时间】:2017-03-16 07:30:59
【问题描述】:
我正在测试一个使用 Dao 层的服务类。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class AppServiceTest {
@Autowired
@InjectMocks
private AppService appService;
private AppConfig appConfig = new AppConfig(), appConfigOut = new AppConfig();
@MockBean //This statement is under inspection in the problem
private AppDao appDao;
@Before
public void setUp() throws Exception {
String appKey = "jsadf87bdfys78fsd6f0s7f8as6sd";
appConfig.setAppKey(appKey);
appConfigOut.setAppKey(appKey);
appConfigOut.setRequestPerMinute(null);
appConfigOut.setRequestDate(DateTime.now());
MockitoAnnotations.initMocks(this);
}
@Test
public void testFetchAppConfigValidParam() throws Exception {
when(appDao.fetchAppConfig(appConfig)).thenReturn(appConfigOut);
assertThat(appService.fetchAppConfig(appConfig)).isEqualToComparingFieldByField(appConfigOut);
}
在上面的程序中,当我写@MockBean时,测试会抛出NullPointerException,但是当我写@Mock时,测试执行成功。我认为被调用的 appDao 是在appService 中定义并访问数据库的实际应用程序。这是因为测试所花费的时间大约是 200 毫秒,而其他应用程序的通常测试用例是 60 毫秒-100 毫秒。但我不确定,因为 DAO 真正访问数据的其他情况需要 400 毫秒到 500 毫秒。
我怎么知道 mock 确实在工作,当 appService 从内部调用 appDao 方法时,它实际上是 mock。是否有任何编程方式来验证这一点。
附:如果@Mock 在这种情况下工作,那么@MockBean 在spring boot 中很有用。
【问题讨论】:
-
问题是你的代码。从您的测试中删除
@InjectMocks和MockitoAnnotations.initMocks(this);。当使用@MockBean时,Spring Boot 会为您处理所有这些...您基本上是在与当前设置进行斗争。 -
@M.Deinum 它对我有用。谢谢。但是,如果我同时使用 MockBean 和 Mock,我应该如何在场景中使用
MockitoAnnotations.initMocks(this);。 -
你不应该使用任何一种,但不要混合使用,因为这会导致你出现问题。此外,如果您要自己替换 bean 实例中的变量,您还必须在测试后刷新应用程序上下文。
-
如果我不想模拟 bean 怎么办。这是一个描述这种情况的问题。 [Mock 和 MockBean] (stackoverflow.com/questions/42833049/…)
-
@M.Deinum 上述问题的解决方案是什么?
标签: java unit-testing spring-boot mockito spring-boot-test