繁体   English   中英

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

[英]Can I mock some static methods only using powermock+mockito+junit?

我正在使用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有关吗?

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

谢谢。

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

}

希望能帮助到你!

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM