如何模拟私有dao变量?

mem*_*und 9 java junit mockito powermock

dao.create()在测试方法时,我有一个想要模拟的调用.但我错过了一些东西,因为我还在接受NPE.这有什么不对?

class MyService {
    @Inject
    private Dao dao;

    public void myMethod() {
        //..
        dao.create(object);
        //
    }
}
Run Code Online (Sandbox Code Playgroud)

如何模拟dao.create()调用?

@RunWith(PowerMockRunner.class)
@PrepareForTest(DAO.class)
public void MyServiceTest {

    @Test
    public void testMyMethod() {
        PowerMockito.mock(DAO.class);

        MyService service = new MyService();
        service.myMethod(); //NPE for dao.create()
    }
}
Run Code Online (Sandbox Code Playgroud)

Cae*_*alf 5

你没有注射DAO.使用mockito,您可以更改测试类以使用@InjectMocks并使用mockito runner.

@RunWith(MockitoJUnitRunner.class)
public void MyServiceTest {
    @Mock
    private Dao dao;
    @InjectMocks
    private MyService myService;
    ...
}
Run Code Online (Sandbox Code Playgroud)

您可以在Inject Mocks API中阅读有关InjectMocks的更多信息

更简单的方法是通过构造函数将注入更改为注入.例如,您可以将MyService更改为

class MyService {
    ...
    private final Dao dao;

    @Inject
    public MyService(Dao dao) {
        this.dao = dao;
    } 
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后你的测试你可以简单地通过设置中的模拟DAO.

...
@Mock
private Dao dao;

@Before
public void setUp() {
    this.dao = mock(Dao.class);
    this.service = new MyService(dao);
}
...
Run Code Online (Sandbox Code Playgroud)

现在你可以verify用来检查是否create被调用,如:

...
   verify(dao).create(argThat(isExpectedObjectBeingCreated(object)));
}

private Matcher<?> isExpectedObjectBeingCreated(Object object) { ... }
Run Code Online (Sandbox Code Playgroud)

使用构造函数注入将使您的依赖关系更清晰,其他开发人员将在创建测试时有所帮助:)