Mockito和私有字段/注入的bean

时间:2018-11-21 10:46:04

标签: java junit mockito junit5

在Mockito测试中访问/设置Java-EE-Bean中的私有字段的标准方法是什么?测试如下,但是如果我运行(Mockito-)测试,则MyDao字段为空。向MyDao抛出NullPointerException。

但是我不想使用反射-还有另一种方法可以做到这一点,还是服务的体系结构不好?

要测试的课程:

@Stateless
public class MyServiceImpl extends AbstractService {

@Inject
private MyDao myDao;

public MyEntity findByIdOrThrow( final long id ) throws Exception {
        if ( id > 0 ) {
            final MyEntity entity = myDao.findById( id );
            if ( entity == null ) {
                throw new Exception(  );
            } else {
                return entity;
            }
        } else {
            throw new Exception(  );
        }
    }

测试类:

public class MyServiceImplTest {
private MyServiceImpl myServiceImpl;

@BeforeEach
public void setup() {
    myServiceImpl = new ServiceServiceImpl();
}

@Test
public void findByIdOrThrow() throws Exception {
    Long id = 1L;
    when( myServiceImpl.findByIdOrThrow( id ) ).thenReturn( new MyEntity() );        
}}

测试类已更新:

import static org.mockito.Mockito.when;

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.junit.MockitoJUnitRunner;

import de.myapp.dao.MyDao;
import de.myapp.entity.MyEntity;

@RunWith( MockitoJUnitRunner.class )
public class ServiceServiceImplTest {

    @Mock
    public MyDao myDao;

    @InjectMocks
    public MyServiceImpl myServiceImpl;

    @Test
    public void findByIdOrThrow() throws Exception {
        final Long id = 1L;
        when( myServiceImpl.findByIdOrThrow( id ) ).thenReturn( new MyEntity() );
    }

}

1 个答案:

答案 0 :(得分:2)

我假设MyDao是一个接口。您必须在测试课程中执行以下操作:

@Mock
private MyDao myDao;

@InjectMocks
private MyServiceImpl myServiceImpl;

并删除@BeforeEach方法。这样,您将在te类中注入dao的模拟。使用Mockito.when,您将正确设置dao-mock以模拟您的真实dao。不要忘记更改测试声明,如下所示:

@RunWith(MockitoJUnitRunner.class)
public class MyServiceImplTest

如果使用的是JUnit 5,则测试类声明应为以下内容:

@ExtendWith(MockitoExtension.class)
@RunWith(JUnitPlatform.class)

在最后一种情况下,您可以省略@RunWith,但我不确定。