如何使用Mockito模拟System.getProperty

时间:2018-01-30 20:02:42

标签: java unit-testing mockito

我在org.mockito.plugins.MockMaker文件中添加了mock-maker-inline文本,并将其放在test / resources / mockito-extensions中

在我的测试案例中,我正在使用:

System system = mock(System.class);
when(system.getProperty("flag")).thenReturn("true");`

但是我得到以下例外:

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
   Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.

感谢任何建议

3 个答案:

答案 0 :(得分:2)

System.getProperty()方法是静态,为了模仿此方法,您需要使用PowerMock

以下是一个例子:

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

import static org.junit.Assert.assertEquals;

@RunWith(PowerMockRunner.class)
@PrepareForTest(System.class)
public class ATest {

    @Test
    public void canMockSystemProperties() {
        PowerMockito.mockStatic(System.class);
        PowerMockito.when(System.getProperty("flag")).thenReturn("true");

        assertEquals("true", System.getProperty("flag"));
    }
}

这使用:

  • junit:junit:4.12
  • org.mockito:mocktio-core:2.7.19
  • org.powermock:powermock-api-mockito2:1.7.0
  • org.powermock:powermock-module-junit4:1.7.0

注意:@davidxxx's suggestion避免需要通过隐藏正面后面的所有System访问来模拟这一点是非常明智的。另一种避免模拟System的方法是在运行测试时将所需的值设置为系统属性,System Rules提供了一种在上下文中设置和拆除系统属性期望的简洁方法Junit测试。

答案 1 :(得分:1)

Mockito(1为2)并没有提供模拟静态方法的方法 因此添加mockito-inline对于模拟System.getProperty()方法毫无用处。

一般来说,嘲弄静态方法通常是一个坏主意,因为它会鼓励一个糟糕的设计 在你的情况下,情况并非如此,因为你需要模拟一个当然不能改变的JDK类。

所以你有两种方式:

  • 使用Powermock或任何允许模拟静态方法的工具

  • 将System静态方法调用包装在提供实例方法的类中,例如SystemService

最后一种方法实际上并不难实现,除此之外还提供了一种在需要的地方注入此类实例的方法 这比两个语句之间隐藏的system.getProperty("flag")语句产生更清晰的代码。

答案 2 :(得分:0)

您还可以使用实际方法,在每次测试之前和之后准备和删除配置:

@Before
public void setUp() {
    System.setProperty("flag", "true");
}

@After
public void tearDown() {
    System.clearProperty("flag");
}