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

时间:2017-10-31 23:07:41

标签: java unit-testing junit mockito powermock

我正在使用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,而不是method2method3

@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有关吗?

我的测试可能看起来不太优雅,但我在发布之前简化了我的用例。

谢谢。

2 个答案:

答案 0 :(得分:3)

是的,可以使用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;
}

}

希望它有所帮助!

答案 1 :(得分:2)

如果你想要实现更多的方法,而不是需要模拟的方法(特别是在你的情况下它只有一个),那么我会选择间谍而不是模拟:

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之外的所有方法都将通过实际实现来调用。