在标记此Answer的副本之前,请理解答案并不能解决我的问题。答案提供了一个解决方案,我在当前方法中使用when()
。在我的问题中,正在初始化UserDao
,否则无法传递被测方法和模拟对象。
有一个界面的参考,由MyBatis初始化。我不能在测试中直接嘲笑它,因为该对象没有被传递到测试的主题中。我必须通过模拟构造函数来PowerMock它。由于没有构造函数调用该接口,因此PowerMock会抛出异常。
java.lang.ArrayIndexOutOfBoundsException: 0
at org.powermock.api.mockito.internal.expectation.AbstractConstructorExpectationSetup.withAnyArguments(AbstractConstructorExpectationSetup.java:100)
代码如下所示
class UserServiceTest{
@AutoWired
UserService userService;
@Mock
UserDao userDao;//This is a reference to the interface (UserDao) which is mapped using MyBatis
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
//The Program fails at the below statement
PowerMockito.whenNew(UserDao.class).withAnyArguments().thenReturn(userDao);
@Test
public void testFetchDetails() throws Exception {
when(userDao.fetchDetails(any(ParameterOne.class)).thenReturn(null);
assertThat(userService.fetchDetails(new ParameterOne())).isNull();
}
}
如果我在没有PowerMock的情况下运行程序,则会访问实际的数据库并返回正确的结果。访问数据库也会导致Test的运行时间减慢,最多可达500ms。
如何模仿UserDao userDao
?如果我不能嘲笑如何在这种情况下执行单元测试。我无法更改我测试的代码。
P.S。如果您仍然建议我避免使用PowerMock,请建议更好的"在这种情况下的另类。
P.P.S请注意,我没有测试Dao Layer而不是使用Dao Layer的服务,因此,我必须模仿DaoLayer来检查服务的行为是否正确。答案 0 :(得分:0)
该应用程序是一个spring-boot应用程序。我将@InjectMocks
用于测试类,@Mock
用于任何需要模拟的对象。
@RunWith(SpringRunner.class)
class UserServiceTest{
@InjectMocks
UserService userService;
@Mock
UserDao userDao;//This is a reference to the interface (UserDao) which is mapped using MyBatis
...
}
这很有用,我可以在模拟对象上直接使用when()/ given()。