如何使用PowerMock模拟非静态方法

Bal*_*ala 6 non-static powermock

我试图模拟我的测试方法的内部方法调用

我的班级看起来像这样

public class App {
public Student getStudent() {
    MyDAO dao = new MyDAO();
    return dao.getStudentDetails();//getStudentDetails is a public 
                                  //non-static method in the DAO class
}
Run Code Online (Sandbox Code Playgroud)

当我为方法getStudent()编写junit时,PowerMock中是否有一种方法可以模拟该行

dao.getStudentDetails();
Run Code Online (Sandbox Code Playgroud)

或者让app类在junit执行期间使用mock dao对象而不是连接到DB的实际dao调用?

Mat*_*man 8

您可以使用whenNew()PowerMock中的方法(请参阅https://github.com/powermock/powermock/wiki/Mockito#how-to-mock-construction-of-new-objects)

完整测试案例

import org.junit.*;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.junit.Assert.*;

@RunWith(PowerMockRunner.class)
@PrepareForTest(App.class)
public class AppTest {
    @Test
    public void testGetStudent() throws Exception {
        App app = new App();
        MyDAO mockDao = Mockito.mock(MyDAO.class);
        Student mockStudent = Mockito.mock(Student.class);

        PowerMockito.whenNew(MyDAO.class).withNoArguments().thenReturn(mockDao);
        Mockito.when(mockDao.getStudentDetails()).thenReturn(mockStudent);
        Mockito.when(mockStudent.getName()).thenReturn("mock");

        assertEquals("mock", app.getStudent().getName());
    }
}
Run Code Online (Sandbox Code Playgroud)

我为这个测试用例制作了一个简单的Student类:

public class Student {
    private String name;
    public Student() {
        name = "real";
    }
    public String getName() {
        return name;
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 1

为了充分利用模拟框架,必须注入 MyDAO 对象。您可以使用 Spring 我们的 Guice 之类的东西,或者简单地使用工厂模式来为您提供 DAO 对象。然后,在单元测试中,您将拥有一个测试工厂来为您提供模拟 DAO 对象而不是真实的 DAO 对象。然后你可以编写如下代码:

Mockito.when(mockDao.getStudentDetails()).thenReturn(someValue);
Run Code Online (Sandbox Code Playgroud)