繁体   English   中英

模拟静态方法

[英]Mocking a static method

下面是我要测试的方法。 我正在使用TestNG框架进行单元测试。

class Random{

    List<String> namesOfLinks;

    public List<String> methodIwantToTest(List<String> cktNames) {
            Map<String, Graph> maps =   DataBaseReader.getGraphs(cktNames);
            for (Entry<String, Graph> entry : maps.entrySet()) {
                graphList.add(entry.getValue().getName());
            }
    }

    return namesOfLinks;
}

我正在上面的类中编写方法“ methodIwantToTest”的测试用例。 我可以提供一些虚拟的cktNames并让该方法执行如下。

@Test (dataProvider = "dp")
public void test_methodIwantToTest(List<String> cktNames, List<String> expectedLinkNames){
    Random rm = new Random();
    List<String> actual = rm.methodIwantToTest(cktNames);
    Assert.assertEquals(actual,expectedLinkNames);
} 

现在出现了问题。 当我在'rm'引用上调用实际方法时,它将对另一个API进行静态方法调用。 为了我的“方法”起作用,它必须返回一些东西。 我在互联网上搜索并找到“ easymock”作为解决方案。 但是我无法使用“ easyMock”来模拟静态方法(DataBaseReader.getGraphs())。 我必须模拟该方法,以便它返回已定义类型的映射。 任何建议都很好。 谢谢 !!

其他问题涉及如何测试静态方法。 但是我的想法是在测试实例方法时模拟静态方法。

您需要PowerMock直接模拟静态方法。 参见https://github.com/jayway/powermock/wiki/TestNG_usage

我建议将适配器模式与依赖注入技术结合使用。 创建一个包含要模拟的所有方法的接口:

public interface IDatabase {
    Map<String, Graph> getGraphs(List<String> names);
}

显然, Database并没有实现您刚发明的接口(该方法无论如何都是static的),但是您可以创建一个适配器类:

public class DataBaseReaderAdapter implements IDatabase {
    public Map<String, Graph> getGraphs(List<String> names) {
        return DataBaseReader.getGraphs(names);
    }
}

将此类的实例作为您要测试的类中的构造函数参数:

public class Random {
    private readonly IDatabase _database;

    public Random(IDatabase database) {
        _database = database;
    }
}

以及何时要调用该方法:

Map<String, Graph> maps = _database.getGraphs(cktNames);

在测试中,使用任何模拟框架来创建IDatabase的模拟,然后将该模拟传递给Random

尽管此技术乍看之下似乎很复杂,但它往往会导致更好的设计,在该设计中,类的依赖关系更加可见,并且所有内容都变得更易于测试。

暂无
暂无

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

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