java如何对foo bar调用方法_关于java:如何测试工厂方法传递给构造函数的参数?...

在单元测试中,测试一个使用静态工厂方法创建对象的类时,遇到挑战是验证输入参数如何影响构造函数。讨论了如何在不直接测试Bar构造函数的情况下,验证Foo类的createBarOf方法中参数处理的正确性。建议通过测试Bar对象的最终状态来间接验证参数逻辑,因为Bar的构造函数内部操作导致的任何变化应反映在Bar的公共行为上。
摘要由CSDN通过智能技术生成

我遇到了一个我真不知道如何解决的情况。我刚刚创建了一个类Foo,它包含一个静态工厂方法,使用一些参数创建类Bar,因此Foo是一种工厂类。现在我想测试这个方法,但问题是,这些参数在内部被修改,以创建在Bar上调用构造函数所需的变量。作为测试的一部分,我可以测试我得到Bar的最终对象,但我不知道如何验证传递给构造函数的参数。

public class Foo {

public Bar createBarOf(String argumentOne, String argumentTwo) {

String argumentForBar = argumentOne + argumentTwo;

return new Bar(argumentForBar);

}

}

有什么建议?

编辑

为了使问题更清楚,这是Bar类。

public class Bar {

private final String SUFFIX ="BarSuffix";

private String field;

public Bar(String argumentForBar) {

field = argumentForBar + BAR_SUFFIX;

}

}

所以,考虑到这个构造函数。当我在Foo中测试createBarFor(argumentOne,argumentTwo)时,我无法弄清楚如何测试那个argumentOne和argumentTwo用于创建Bar,除非我还在该测试中测试Bar构造函数并假设Bar的内部是什么。 argumentOne和argumentTwo不是Bar的存储字段,而是变量来计算对象中字段的值。

只需使用createBarOf并对返回的Bar对象断言您的期望。 当你使用参数a和b创建ab时,你不应该试图断言ab被传递给构造函数,当你获得Bar对象时,它已经被包含了。

由于createBarOf内没有退出逻辑(从方法返回的执行分支),因此您不必专门测试有关此方法的任何内容。

但是我不应该在Bar类的特定单元测试中测试我的期望吗?测试栏作为Foo测试的一部分,将为Bar(至少对于它的构造函数)进行冗余单元测试。我可以在这里测试工厂方法和Bar构造函数,但Bar的单元测试不包含其构造函数的测试似乎很奇怪。而只是测试我从工厂方法得到一个Bar类型的对象不能确保为构造函数创建参数的逻辑(实际代码比concat两个字符串更复杂)

@Kilian:我并不是说你测试你收到了一个Bar对象。我的意思是你在返回的Bar对象上执行断言;这个论点有什么影响?它改变了一些变量吗?然后在Bar.getArgument()上断言。您的单元测试可以包含多个分层单元:请查看我的答案stackoverflow.com/a/17731324/1864167。

我遇到的问题是传递的参数永远不会存储在Bar对象中。它在构造函数中用于填充其他对象的列表。有我的问题,没有Bar.getArgumentForBar()但Bar.getNewCalculatedValue()。如果我想验证Foo工厂方法使用传递的参数,除非有单一测试中捕获这些参数的方法,我还必须测试Bar中的构造函数逻辑,我想在单元测试中做具体的。

你正在寻找一个太直接的结果,我无法让它更清晰,因为你的问题太抽象了。当你传入"a"和"b"时,这对你的Bar构造有影响,对吧?使用断言验证此最终效果。我建议你也看看我的博客,我稍微详细说明了这一点(见该帖的结尾)。

我编辑了我的注释,以显示如何在Bar构造函数中使用参数。在该代码中,没有办法验证argumentOne和argumentTwo,因为它们没有存储在任何地方,而是用于使用常量来计算"字段"。这个例子是我的问题的简化版本,以显示除非测试还测试Bar构造函数,否则传递的参数是如何解决的。

是的,但你仍然没有展示它是如何使用的。只需测试最终使用field的代码,看看是否完美无缺。它含蓄地测试了这一点。

@Jeroen是对的。最终,私有字段field必须在类中有某种用途,即使没有明确的getter。在设置之后断言field的用法。

好的,所以你要说的是,测试工厂方法的唯一方法是验证field包含构造函数中的逻辑应用后的预期数据。我问这个的原因是因为在我看来,如何使用field或它包含什么并不重要。测试应该只验证构造函数的参数的逻辑,而不是构造函数本身。这应该是Bar的单元测试的一部分,而不是Foo的单元测试。但是如果没有办法做到这一点,那么我应该得到field并断言它以便构造函数也在这里进行测试。

不,我们明确表示您不应该特别测试field。我们说你应该只使用Bar实例并测试它。 field值将在某处使用,最终将通过您可以测试的公共方法进行隐式测试。如果您能够显示如何使用它的明确示例,这将更容易解释;)

对不起,但我不能把真实的例子因为很大。在那个,在工厂方法中计算的参数在构造函数中使用,以在其中创建另一个复杂对象。这就是为什么对我来说测试方法的使用是没有意义的,因为它依赖于其他几个方法。这些其他的有自己的单元测试,因此在工厂方法中测试使用它们将是多余的。我期望的行为会使测试变得复杂,这应该是相当简单的。我结束了访问里面的对象并验证我期望的值

我有类似的情况。 如果您的Bar有一个equals方法,您可以随时构建您希望工厂在测试中构建的Bar ...

assertThat(actualbar).isEqualTo(expectedBar)

但是如果没有任何意义可以拥有"等于",或者你不能因为某种原因改变"Bar",那么你可能没有太多选择,只能通过反射进入Bar的私人领域,看看是否 设置正确的值。

例如(这使用名为ReflectionTestUtils的"spring-test"类)...

assertThat(ReflectionTestUtils.getField(actualBar,"argumentForBar")).isEqualTo(expectedValue);

正如之前的回复所评论的那样,在Bar的特定单元测试中测试构造函数更有意义,而不是将其作为Foo中工厂方法测试的一部分。对我来说,这里应该测试的是为Bar构造函数创建最终参数的逻辑,而不是构造函数的工作原理(应该是另一个测试)。但是如果没有其他方法,我想我将不得不在这里调用构造函数来测试结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值