验证是否创建了临时对象

时间:2018-10-05 14:31:45

标签: java mocking mockito

我在Java上下文中,正在使用Mockito(但我不受其约束)来满足基本的模拟需求。

我有这样的代码

public class AuditInfoSerializer {

    [..]

    public Map<String, Object> doStuff(Object a) {
        doOtherStuff("hello", new TempClass(someField, <someParams>));
        doOtherStuff("world", new TempClass(someField, <otherParams>));
        return getResult();
    }
}

在一个测试中,我想验证当我调用TempClass方法时,是否使用正确的参数集创建了两个doStuff实例。

这有可能吗?

2 个答案:

答案 0 :(得分:1)

您不想验证被测对象上的临时数据。您要模拟依赖关系并断言被测对象的行为:即使用此输入,您将获得此输出。
模拟验证是模拟方法的折衷,模拟方法什么也不返回,只产生副作用。
因此,仅在没有选择的情况下使用它。
在单元测试中,您要声明的是要返回的测试方法Assert.assertEquals(...)
使用Mockito.verify(...)而不使用 import React, {Component } from 'react'; import {View, Text} from 'react-native' import {BarChart} from 'react-native-chart-kit' export default class App extends Component{ render() { const data = { labels: ['January', 'February', 'March', 'April', 'May', 'June','July'], datasets: [{ data: [ 2500, 4500, 2800, 800, 9900, 4300,9100 ] }] } const chartConfig = { backgroundGradientFrom: '#1E2923', backgroundGradientTo: '#08130D', color: (opacity = 1) => `rgba(26, 255, 146, ${opacity})`, } return(<BarChart //style={graphStyle} data={data} width={400} height={220} chartConfig={chartConfig} />) }}

答案 1 :(得分:1)

在大多数情况下,我同意@davidxxx关于模拟验证权衡的观点。如果您有一个设置可以对结果进行断言(例如,作为结果而创建的地图),那就去吧!

从API角度来看,doStuff是一种简单的直接方法:向其中扔东西,取回东西。您感兴趣的信息将包含在地图中(这就是您的主张)。

doStuff返回某些信息之前,引擎盖上有很多事情。许多人在测试材料时往往希望破坏封装。他们一直在寻找发现幕后事件的方法。我相信那是完全自然的。但是,当然,这也是一种反模式。不管您使用(错误)使用哪种工具来打破自然界限(模拟框架,自定义反射,代码库中的“后门”等)都无关紧要。总是错的。正如@Michael指出的那样,对doOtherStuff的调用确实是实现细节。从调用doStuff的客户端代码的角度来看。它对如何创建地图感兴趣吗?我对此表示怀疑。这也应该是您的测试视角。

关于在测试中使用验证的最后一件事。我想减轻折衷的说法。我真的不喜欢这里的概括。与真实断言相比,验证并不是总是更具吸引力的选择:

// Valid test without any verifaction
@Test
void method_foo_returns_gibberish (@Mock SomeInput someInput) {

    // Maybe this is just to prevent an NPE ...
    when(someInput.readStuff()).thenReturn("bla");

    assertEquals("gibberish", Foo.foo(someInput));

}


// Test made possible by verification
@Test
void method_foo_is_readonly (@Mock SomeInput someInput) {

    Foo.foo(someInput);
    verify(someInput.readStuff());
    verifyNoMoreInteractions(mockedList);

}

这只是我能想到的最明显的例子。仅有少数BDD天才致力于围绕验证驱动的测试构建其整个体系结构! Here is an excellent article by Martin Fowler

在谈论测试时,大多数时候没有黑白两色。使用模拟和验证意味着编写不同测试。

一如既往,这是关于选择正确的工具。