使用testng,mockito和powermock模拟系统类方法

时间:2017-07-24 16:14:21

标签: mockito testng powermockito

我目前正在为使用函数System.getenv("some_environment_variable")

的遗留代码编写测试

当我尝试使用mockito和powermock(在testng框架下使用)来模拟这些变量时出现问题

到目前为止我做的是

@BeforeClass
public void setup() {
    PowerMockito.mockStatic(System.class);
    PowerMockito.when(System.getenv("hello")).thenReturn("world");
}

@Test
public void test() {
    assertEquals(System.getenv("hello"), "world");
}

但是当我尝试运行上面的代码时,我收到以下错误:

  

org.mockito.exceptions.misusing.MissingMethodInvocationException:   when()需要一个参数,该参数必须是模拟'上的方法调用。   例如:       当(mock.getArticles())thenReturn(文章);

     

此外,此错误可能会显示,因为:

     
      
  1. 你存在以下任何一个:final / private / equals()/ hashCode()方法。   这些方法无法进行存根/验证。   不支持在非公共父类上声明的模拟方法。

  2.   
  3. 在()内部,你不会在模拟上调用方法,而是在其他对象上调用方法。

  4.   

所以Iv阅读并看到在尝试使用模拟类本身来模拟一个方法时引发了这个错误,但这不是这里的情况。

2 个答案:

答案 0 :(得分:2)

经过很长一段时间的努力,这就是我设法做到的。

简而言之,为了让powermockito和TestNG相互合作,您必须执行以下操作(引用下面共享链接的博客文章,以便答案完整,即使博客也会有用在以后的某个时间段不可用)

  1. 配置TestNG以使用PowerMock对象工厂:您可以通过套件xml的object-factory标记中的属性<suite>或通过@org.testng.annotations.ObjectFactory带注释的方法,通过扩展org.testng.IObjectFactory

  2. 返回powermock的TestNG接口org.powermock.modules.testng.PowerMockObjectFactory实现,org.powermock.modules.testng.PowerMockTestCase(或)
  3. 使用@PrepareForTest准备静态类以供PowerMockito嘲笑

  4. 有关详细信息,请参阅this博客。

    这是一个工作样本:

    import org.powermock.api.mockito.PowerMockito;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.testng.IObjectFactory;
    import org.testng.annotations.BeforeClass;
    import org.testng.annotations.ObjectFactory;
    import org.testng.annotations.Test;
    
    import static org.testng.Assert.assertEquals;
    
    @PrepareForTest(System.class)
    public class SampleTestClass {
        @BeforeClass
        public void setup() {
            PowerMockito.mockStatic(System.class);
            PowerMockito.when(System.getenv("hello")).thenReturn("world");
        }
    
        @Test
        public void test() {
            assertEquals(System.getenv("hello"), "world");
        }
    
        @ObjectFactory
        public IObjectFactory getObjectFactory() {
            return new org.powermock.modules.testng.PowerMockObjectFactory();
        }
    
    }
    

    我使用以下依赖项来创建此示例

    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-testng</artifactId>
        <version>1.7.0</version>
        <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito</artifactId>
        <version>1.7.0</version>
        <scope>test</scope>
    </dependency>
    

答案 1 :(得分:0)

还有另一个JUnit库可以帮助您:system-rules,它允许您 - 除其他外 - 设置和恢复环境变量。它与JUnit @Rule s

一起使用