如何模拟由MyBatis初始化的界面参考?

时间:2017-03-15 07:08:09

标签: java unit-testing mocking dao powermock

在标记此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来检查服务的行为是否正确。

1 个答案:

答案 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()。