java - 如何仅在 x :th call? 上返回模拟项目

标签 java testing mockito powermock powermockito

我在使用 PowerMock 时遇到了一个问题,如果我只想返回一个模拟项一次,我感觉被迫创建丑陋的代码。 作为示例,我有以下代码:

mockMap = spy(new HashMap());
HashMap<String, String> normalMap = new HashMap<>();
HashMap<String, String> normalMap2 = new HashMap<>();
HashMap<String, String> normalMap3 = new HashMap<>();
whenNew(HashMap.class).withNoArguments()
    .thenReturn(normalMap)
    .thenReturn(mockMap)
    .thenReturn(normalMap2)
    .thenReturn(normalMap3);

这当然有效,但感觉非常笨重,特别是当我需要为每个新调用创建一个新的 HashMap 时。

所以我的问题是:有没有办法告诉 PowerMock 在一定数量的调用后它应该停止干扰?

编辑: 阅读答案后,我得到以下结论:

final AtomicInteger count = new AtomicInteger(0);
whenNew(HashMap.class).withNoArguments().thenAnswer(invocation -> {
switch (count.incrementAndGet())
{
        case 1:
            return mockMap;
        default:
            return new HashMap<String, String>();
    }
});

但是,它使用以下代码给了我一个 StackOverFlowError:

describe("test", () -> {
    beforeEach(() -> {
        mockStatic(HashMap.class);
        final AtomicInteger count = new AtomicInteger(0);
        whenNew(HashMap.class).withNoArguments().thenAnswer(invocation ->
        {
            switch (count.incrementAndGet())
            {
                case 5:
                    return mockMap;
                default:
                    return new HashMap<String, String>();
            }
        });
    });
    it("Crashes on getting a new HashMap", () -> {
        HashMap map = new HashMap<>();
        map.put("test", "test");
        HashMap normal = new HashMap<String, String>();
        expect(normal.containsValue("test")).toBeTrue();
    });
});

值得注意的是,我在较大的测试中没有mockStatic(HashMap.class),它会出现相同的错误(如果删除mockStatic调用,我就会摆脱这些错误)

一个可行的解决方案(但感觉像是一个解决方法)是通过将默认语句编辑为:

default:
    normalMap.clear();
    return normalMap;

最佳答案

您可以使用 thenReturn有多个参数,如下所示:

whenNew(HashMap.class).withNoArguments()
    .thenReturn(normalMap, mockMap, normalMap2, normalMap3);

或者自己写Answer像这样:

whenNew(HashMap.withNoArguments()).doAnswer(new Answer() {
    private int count = 0;

    public Object answer(InvocationOnMock invocation) {
        // implement your logic
        // if (count ==0) etc.
    }
});

关于java - 如何仅在 x :th call? 上返回模拟项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43915376/

相关文章:

java - 在比较器中处理 IOException 的正确方法是什么?

mockito - 为什么 Mockito 给我模拟对象的默认值?

mockito - 无法初始化插件: interface org.mockito.plugins.MockMaker

Scala Play 框架 - 运行涉及 Akka 的测试时出现 "cannot enqueue after timer shutdown"错误

java - 从数据库中获取数据后 jTable 不显示任何内容

java - 使参数在应用程序中可用

java - 扩展 JSP 自定义标签

c# - 仅包含私有(private)字段的流畅断言 Should().BeEquivalentTo

hadoop - 测试Hadoop到Teradata的流程

java - 如何使用 JMeter 在 JSF 应用程序中上传文件