如何嘲笑使用JUnit,EasyMock的或PowerMock静态final变量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何嘲笑使用JUnit,EasyMock的或PowerMock静态final变量相关的知识,希望对你有一定的参考价值。

参考技术A 在方法内部定义的叫“局部变量”,而不是静态变量,局部变量不能加static,包括protected, private, public这些也不能加。静态变量是定义在类中,方法体外面的。 如果你清楚JVM,应该知道局部变量是保存在栈中的,而静态变量保存于方法区本回答被提问者和网友采纳

Powermock 不嘲笑 Consul 课程

【中文标题】Powermock 不嘲笑 Consul 课程【英文标题】:Powermock not mocking for Consul class 【发布时间】:2020-05-01 20:23:37 【问题描述】:

这是一个我想测试的类方法,我想模​​拟所有的 Consul 调用。 但是,每当我作为 junit 测试运行时,我都会收到 Consul builder 的 NullPointerException 错误。它没有为 Consul.class 创建模拟连接。任何人都可以帮助我。

public Dependency checkConsulHealth(String consulUrl, String aclToken) 
    try 
        Consul.builder().withUrl(consulUrl).withAclToken(aclToken).build();
        LOGGER.debug("Consul connection successful");
        return new Dependency(consulUrl, CONSUL_SERVICE, SUCCESS_MESSAGE, SUCCESS_STATUS);
     catch (Exception exception) 
        LOGGER.debug("Consul connection unsuccessful");
        return new Dependency(consulUrl, CONSUL_SERVICE, ERROR_MESSAGE, ERROR_STATUS);
    

这是我的测试类,我正在尝试测试我的 healthCheckService 类方法。

@RunWith(PowerMockRunner.class)
@PrepareForTest(fullyQualifiedNames = "com.orbitz.consul.Consul")
public class TestHealthCheckService 

    private static final String CONSUL_URL = "Consul";
    private static final String ACL_TOKEN = "123";

    @InjectMocks
    private HealthCheckService healthCheckService;

@Before
public void init() 
    MockitoAnnotations.initMocks(Consul.class);



@Test
public void testCheckConsulHealth() 

    PowerMockito.mockStatic(Consul.class);
    Dependency dependency1 = new Dependency(CONSUL_URL, CONSUL_SERVICE, SUCCESS_MESSAGE, 
         SUCCESS_STATUS);
    System.out.println("From mock "+Consul.builder());
    PowerMockito.when(Consul.builder()
                            .withUrl(CONSUL_URL)
                            .withAclToken(ACL_TOKEN)
                            .build())
                            .thenReturn(null);
    Dependency dependency2 = healthCheckService.checkConsulHealth(CONSUL_URL, ACL_TOKEN);
    assertEquals(dependency1, dependency2);

我的 POM.xml 依赖项是我使用以下依赖项的地方

   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>


    <!-- https://mvnrepository.com/artifact/org.powermock/powermock-api-mockito2 -->
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito2</artifactId>
        <version>2.0.4</version>
        <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.powermock/powermock-module-junit4 -->
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4</artifactId>
        <version>2.0.4</version>
        <scope>test</scope>
    </dependency>

【问题讨论】:

【参考方案1】:

我不使用也不知道 Consul 客户端,但您的问题与您的依赖关系无关:基本上您必须模拟所有步骤。

请仅将以下示例(关于构建器模式)作为建议,并根据您的情况使用 PowerMockito 替换 Mock:

Foo f = mock(Foo.class);
FooBuilder b = mock(FooBuilder.class);
when(b.enableAlpha()).thenReturn(b);
when(b.disableBeta()).thenReturn(b);
when(b.increaseGamma()).thenReturn(b);
when(b.build()).thenReturn(f);

【讨论】:

用 this 试过了,但是 mockStatic 方法没有为 Consul 创建模拟对象。

以上是关于如何嘲笑使用JUnit,EasyMock的或PowerMock静态final变量的主要内容,如果未能解决你的问题,请参考以下文章

JUnit Easymock 意外的方法调用

easymock+junit+spring学习·

使用 Powermock 时出现 NoClassDefFoundError

JSF - JUnit FacesContext模拟测试

EasyMock:java.lang.IllegalStateException:预期 1 个匹配器,记录 2 个

Android单元测试没有被嘲笑