java - 模拟不起作用

标签 java junit mocking mockito amazon-dynamodb

每当我运行以下代码时,我都会收到错误:

Wanted but not invoked:
dynamoDBWriter.addItemsToDynamoTable(
    <any>,
    <any>
);
-> at DynamoDBWriterTest.testAllItemsAdded(DynamoDBWriterTest.java:32)

However, there were other interactions with this mock:
dynamoDBWriter.write(
    [{ Item: {} }, { Item: {} }, { Item: {} }, { Item: {} }, { Item: {} }]
);
-> at DynamoDBWriterTest.testAllItemsAdded(DynamoDBWriterTest.java:31)

以下是我的代码:

public class DynamoDBWriterTest {

    DynamoDBWriter dynamoDbWriter;

    @Before
    public void setup() {
        dynamoDbWriter = mock(DynamoDBWriter.class);
    }

    @Test
    public void testAllItemsAdded() {
        List<Item> items = new ArrayList<>();
        for (int index = 0; index < 5; index++) {
            items.add(new Item());
        }
        dynamoDbWriter.write(items);
        verify(dynamoDbWriter, times(5)).addItemsToDynamoTable(any(), any());
    }
}

来自 DynamoDBWriter 的代码:

public void write(List<Item> items) {
        // Initialize the rate limiter to allow capacity units / sec
        // Since we know that the Item we are putting consumes 1 unit throughput.
        RateLimiter rateLimiter = RateLimiter.create(1);

        // Track how much throughput we consume on each put operation
        for (Item item: items) {
            // Let the rate limiter wait until our desired throughput "recharges"
            rateLimiter.acquire();
            addItemsToDynamoTable(table, item);
        }
    }

    protected void addItemsToDynamoTable(Table table, Item item) {
        try {
            table.putItem(item);
        } catch (RuntimeException e) {
            logger.fatal("dynamoDB table.putItem threw exception for:" + tableName, e);
            throw e;
        }
    }

感谢您的帮助。我还添加了我使用的实际“更正/工作”代码:

@Before
    public void setup() {
        dynamoDbWriter = spy(DynamoDBWriter....);
        doNothing().when(dynamoDbWriter).addItemsToDynamoTable(any(), any());
    }

    // Method makes sure that irrespective of the throughput, all the items are added to dynamoDB
    @Test
    public void testAllItemsAdded() {
        List<Item> items = new ArrayList<>();
        for (int index = 0; index < 5; index++) {
            items.add(new Item());
        }
        dynamoDbWriter.write(items);
        verify(dynamoDbWriter, times(5)).addItemsToDynamoTable(any(), any());
    }

最佳答案

当您创建模拟 DynamoDBWriter 时,默认情况下它会覆盖所有带有不执行任何操作的 stub 的方法。当您调用 write 时,Mockito 的替换实现允许验证是否调用了 write,但不允许验证 write< 的任何调用 实现使得。该实现永远不会被调用。

当然,真正的问题是您正在 mock 您正在测试的类(class)。即使使用技术解决方法,测试模拟框架也比模拟被测试的类更容易。一般来说,为被测系统的协作者保留模拟,而不是为被测系统本身保留模拟。 (另请参见 his answer here 中 JB Nizet 的类比。)

<小时/>

也就是说,如果绝对必要,您可以使用真实实例的 spy 并根据需要选择性地重写方法,或者更危险的是,您可以在模拟上使用 thenCallRealMethod :

when(dynamoDbWriter.write(any())).thenCallRealMethod();

有关两者之间的差异以及为什么 thenCallRealMethod 如此危险,请参阅 this SO question .

关于java - 模拟不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33657723/

相关文章:

java - Hamcrest assertThat 在移动项目时不起作用

java - 链表测试....返回类型问题

python - 单元测试设计和模拟

java - 如何通过不同时间调用相同方法在文本文件中写入多行?

java - 如何使用 jdk 1.6.0_20 在 Eclipse 3.6 中配置 tomcat 7?

java - 通过 Ant 运行 Junit 似乎没有使用自定义类运行器

java - Powermockito 私有(private)方法模拟 NullPointerException。调用私有(private)方法

c# - 支持模拟以委托(delegate)为参数的方法的模拟框架

java - 链表的递归

java - 斯坦福-NLP : GC overhead limit excedded when using parser on Tomcat