我可以只使用powermock+mockito+junit来模拟一些静态方法吗?

ygya80vv  于 2021-07-09  发布在  Java
关注(0)|答案(2)|浏览(498)

我正在使用junit+mockito+powermock编写一个测试。
我有一个类,我想测试如下:

public class MyUtils {
    public static Object method1() {} //I want to mock this only
    public static void method2() {}   //I want to keep this as is during my test.
    public static void method3() {}   //I want to keep this as is during my test.
}

我只想嘲笑 method1 但不是 method2 或者 method3 .

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyUtils.class)
public class MyTest {

    @Before
    public void setUpBeforeClass() throws Exception {
        PowerMockito.mockStatic(MyUtils.class);
    }

    @Test
    public void test1() throws Exception {
        when(MyUtils.method1()).thenReturn(something);

        MyUtils.method3(); //method3 is getting mocked with an empty implementation by PowerMockito
    }

    ...
}

我是否可以对一些方法进行模拟,而对一些方法不进行模拟,即在测试期间保留它们的原始实现?mockito+powermock有这种可能吗?
我的测试可能看起来不太优雅,但在这里发布之前,我已经简化了我的用例。
谢谢您。

3zwtqj6y

3zwtqj6y1#

是的,可以使用powermock和junit模拟静态方法,如下所示:

import static org.junit.Assert.*;

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

@RunWith(PowerMockRunner.class)
@PrepareForTest(IDGenerator.class)
public class UserDAOTest {
@Test
public void createShouldReturnAUserId() {

    UserDAO dao = new UserDAO();

    mockStatic(IDGenerator.class);
    when(IDGenerator.generateID()).thenReturn(1);
    int result = dao.create(new User());
    assertEquals(1, result);
    verifyStatic();
}

}

public final class IDGenerator {

static int i;

public static final int generateID() {
    return i++;
}

}

public class UserDAO {

public int create(User user){
    int id = IDGenerator.generateID();
    //Save the user object to the db
    return id;

}

}

public class User {
private int id;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

}

希望有帮助!

laawzig2

laawzig22#

如果你有更多的方法要保留在真正的实现中,而不是那些需要模拟的方法(尤其是在你的例子中只有一种),那么我会选择spy而不是mock:

import static org.powermock.api.mockito.PowerMockito.spy;

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyUtils.class)
public class MyTest {

    @Before
    public void setUpBeforeClass() throws Exception {
        spy(MyUtils.class);
    }

    @Test
    public void test1() throws Exception {
        doReturn(something).when(MyUtils.class, "method1");

        MyUtils.method3(); // this will be a real call
    }

    ...
}

现在所有的方法 method1 将与实际执行一起调用。

相关问题