java - 在参数上调用方法时 PowerMockito 模拟静态方法失败

标签 java unit-testing powermockito

我正在尝试测试一个使用带有许多静态方法的计算器类的类。我已经以类似的方式成功地 mock 了另一个类(class),但事实证明这个类(class)更加顽固。

似乎如果模拟方法包含对传入参数之一的方法调用,则静态方法不会被模拟(并且测试中断)。删除内部调用显然不是一个选项。我在这里明显遗漏了什么吗?

这是一个精简版,其行为方式相同......

public class SmallCalculator {

    public static int getLength(String string){

        int length = 0;

        //length = string.length(); // Uncomment this line and the mocking no longer works... 

        return length;
    }
}

这是测试...

import static org.junit.Assert.assertEquals;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;

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 com.solveit.aps.transport.model.impl.SmallCalculator;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ SmallCalculator.class})
public class SmallTester {

    @Test
    public void smallTest(){

        PowerMockito.spy(SmallCalculator.class);
        given(SmallCalculator.getLength(any(String.class))).willReturn(5);

        assertEquals(5, SmallCalculator.getLength(""));
    }
}

这个问题似乎有些困惑,所以我设计了一个更“现实”的例子。这增加了一个间接级别,因此看起来我正在直接测试模拟方法。 SmallCalculator 类没有变化:

public class BigCalculator {

    public int getLength(){

        int length  = SmallCalculator.getLength("random string");

        // ... other logic

        return length;
    }

    public static void main(String... args){

        new BigCalculator();
    }
}

这是新的测试类...

import static org.junit.Assert.assertEquals;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;

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 com.solveit.aps.transport.model.impl.BigCalculator;
import com.solveit.aps.transport.model.impl.SmallCalculator;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ SmallCalculator.class})
public class BigTester {

    @Test
    public void bigTest(){

        PowerMockito.spy(SmallCalculator.class);
        given(SmallCalculator.getLength(any(String.class))).willReturn(5);

        BigCalculator bigCalculator = new BigCalculator();
        assertEquals(5, bigCalculator.getLength());
    }
}

最佳答案

我在这里找到了答案 https://blog.codecentric.de/en/2011/11/testing-and-mocking-of-static-methods-in-java/

这是有效的最终代码。我已经在原始代码(以及人为的示例)中测试了这种方法,并且效果很好。简单...

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;

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;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ SmallCalculator.class})
public class BigTester {

    @Test
    public void bigTest(){

        PowerMockito.mockStatic(SmallCalculator.class);
        PowerMockito.when(SmallCalculator.getLength(any(String.class))).thenReturn(5);

        BigCalculator bigCalculator = new BigCalculator();
        assertEquals(5, bigCalculator.getLength());
    }
}

关于java - 在参数上调用方法时 PowerMockito 模拟静态方法失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31587770/

相关文章:

unit-testing - Grails 2.0:如何在单元测试中正确使用模拟

asp.net-mvc - ASP.Net MVC 3 : Unit testing controller actions

java - 如何使键事件与单个文本字段一起工作

java - 如果我想使用弹出树查看器创建自定义组合,从哪里开始

c++ - 在 Qt 项目中包括谷歌测试

java - 我可以使用 doReturn 与 PowerMockito 链接返回吗?

java - 如何模拟具有多个参数的静态方法

java - 如何在 Java 中解析命令行参数?

java - 启动 jax-rs 服务器时出错

Mockito错误 "The system cannot find the path specified"