9

dao.create()在测试方法时,我想模拟一个调用。但是我遗漏了一些东西,因为我仍在获得 NPE。这里有什么问题?

class MyService {
    @Inject
    private Dao dao;

    public void myMethod() {
        //..
        dao.create(object);
        //
    }
}

如何模拟 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()
    }
}
4

5 回答 5

5

您没有注入 DAO。使用 mockito,您可以将测试类更改为使用 @InjectMocks 并使用 mockito runner。

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

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

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

class MyService {
    ...
    private final Dao dao;

    @Inject
    public MyService(Dao dao) {
        this.dao = dao;
    } 
    ...
}

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

...
@Mock
private Dao dao;

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

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

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

private Matcher<?> isExpectedObjectBeingCreated(Object object) { ... }

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

于 2012-12-01T18:23:02.403 回答
1

您仍然需要使用您的模拟设置 dao 字段。您可以对此使用反射。

于 2012-11-30T12:49:45.387 回答
1

您需要在服务类中注入/设置模拟对象 DAO。

如果是基于spring的项目,可以看看@Spring Junit Testrunner

于 2012-11-30T12:50:49.380 回答
0

如果你使用new MyService()Dao是永远不会注入的。要注入 Dao,您需要通过ApplicationContext(Spring) 或Injector(Guice) 加载 MyService。就像你在正常的应用程序中一样。

于 2012-11-30T12:51:31.407 回答
0

正如其他人已经说过的那样,您需要以某种方式dao在您的班级中设置该字段。MyService我不确定允许您的测试中的复合运行程序同时使用 Powermock 和 DI 框架运行程序的机制(假设需要 Powermock),但只要您已经在使用 PowerMock(原因在给定示例中不清楚) ,您可以利用Whitebox类更手动地设置 dao。

public void testMyMethod() {
    Dao dao = mock(Dao.class)
    doNothing().when(dao).create(anyObject())); //assuming no return val for dao.create()

    MyService service = new MyService();
    Whitebox.setInternalState(service, "dao", dao);

    service.myMethod(); 
}
于 2012-12-01T17:57:46.113 回答