【问题标题】:Unit testing void methods w/ dependencies that change state with subsequent operation单元测试 void 方法,具有随后续操作改变状态的依赖项
【发布时间】:2013-02-21 15:40:59
【问题描述】:

当依赖项更改传递引用的状态时,我无法对 void 方法进行单元测试并模拟依赖项。我知道可以在 void 方法上观察到副作用,也可以观察到行为,但我很难将这些准则应用于此代码。那里有类似的问题,但我找不到任何处理后续本地更改状态的内容。我正在使用 JUnit 和 Mockito...这是我正在谈论的代码的人为版本:

@Mock
MergingObject mergingObject;

@Override
public void process(Foo foo1) {
    Foo foo2 = getAnInstanceOfFoo(); // private
    Foo foo3 = mergingObject.merge(foo1, foo2); // public
    foo1.copySomeValues(foo3);
}

这里的难题是我是否为 MergingObject 对象创建了一个模拟。当我们模拟对象时,我期望的状态变化会消失,因为 merge(...) 操作永远不会被调用。我可以尝试验证是否使用 foo1 和 foo2 的正确实例调用了 merge(...),但随后的 copySomeValues(...) 调用仍会引发 NullPointerException。

有什么建议吗?

【问题讨论】:

  • 你可以在你的模拟对象上实现合并!不过不是很清楚,您不是说合并更改 foo1 和或 foo2 是吗?
  • 如果我能做到,那就太有趣了。在这种情况下,合并会根据 foo1 和 foo2 的内容返回一个新实例。这需要后续的“复制”步骤。
  • 以为你是在测试副作用一分钟。我对解决这个问题持 KISS 态度,消除副作用。

标签: java unit-testing junit tdd mockito


【解决方案1】:

除非我误解了你,否则你将 mergingObject 设置为模拟,但你没有设置模拟的行为。您需要告诉模拟的 mergingObject 当 .merge 被调用时,返回一些东西。那东西可以是任何你喜欢的东西,你可以验证从 process() 返回的对象是同一个对象。

您可以在 mockito 中使用存根语法设置行为。我从来没有使用过 mockito,但是看看这个网站是这样的

when(mergingObject.merge(something, somethingelse).return(new Foo());

您需要注意如何为某事和其他事指定参数,以便它们与您的 foo1 和 foo2 匹配

【讨论】:

  • 我明白你的意思。现在从 merge(...) 返回一个不同的 Foo 实例当然会从 getAnInstanceOfFoo(...) 调用中删除更改。所以听起来我需要一个验证步骤来确保对 merge(...) 的调用是使用预期的对象,并且我还需要对 copyValues(...) 方法的断言(现在使用我的模拟返回对象)查看该方法是否正确更改状态。
【解决方案2】:

我从您发布的内容中注意到的是,您在测试什么以及为什么要测试还很不清楚。

鉴于 Merge 已被委托给另一个类,该类将拥有自己的一组测试。 我会创建一个 foo1 和一个 foo3 来测试 CopySomeValues。合并根本不会出现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-01
    • 2022-01-02
    相关资源
    最近更新 更多