仅在测试期间使用特殊的构造函数是否有代码味道?

发布于 2024-11-14 11:56:09 字数 612 浏览 1 评论 0原文

假设我有一个类 Foo,它仅使用类 Bar 的实例实例化:

public Foo(Bar x) {
    this.a = x.a();
    this.b = x.b();
    ...
}

现在我想测试 Foo,进一步假设有一个实例具有所需状态的 Bar 很难创建。作为附加约束,字段 a, b, ... 被声明为 Final,因此该字段的 setter 不可用。

一种可能是在 Foo 中创建一个额外的构造函数:

protected Foo(A a, B b, ...) {
    this.a = a;
    this.b = a;
    ...
}

此构造函数仅在测试期间使用,我将在此构造函数的注释中声明它。

问题:这是代码味道吗?

我想到的另一个解决方案是模拟 Bar。想知道在这种情况下这是否是最佳实践?

Assume I have a class Foo which is only instantiated with an instance of class Bar:

public Foo(Bar x) {
    this.a = x.a();
    this.b = x.b();
    ...
}

Now I would like to test Foo, further assuming an instance of Bar with the desired state is difficult to create. As an additional constraint, the fields a, b, ... are declared as final, so setters for this fields are not available.

A possibility would be to create an additional constructor in Foo:

protected Foo(A a, B b, ...) {
    this.a = a;
    this.b = a;
    ...
}

This constructor is only used during testing, which I would declare in the comment for this constructor.

Question: Is this a code smell?

Another solution I was thinking of was mocking Bar. Wonder if its the best practice in this case?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

拥抱影子 2024-11-21 11:56:09

Mocking Bar 更有可能被认为是最佳实践。您应该能够创建一个 MockBar,这样您就可以执行以下操作

Foo foo = new Foo(new MockBar(a, b));

Mocking Bar is more likely to be considered best practice. You should be able to create a MockBar so you can do

Foo foo = new Foo(new MockBar(a, b));
作妖 2024-11-21 11:56:09

我可能会认为这种形式很糟糕,但如果它有效,它就有效。更好的解决方案是创建一个 TestBar 类,它是 Bar 的子类,并覆盖 Bar 中的方法。我想这几乎是在嘲笑该对象,正如您在问题中提到的那样。它更加简洁,并允许您定义可以包含在测试驱动程序中的不同的 Bar 实现。

I would probably consider that poor form, but if it works, it works. A preferable solution would be making a TestBar class that is a sub-class of Bar and overrides the methods in Bar. I guess that's pretty much mocking the object, as you alluded to in your question. It's a lot cleaner and allows you to define a different Bar implementation that can be included by your test driver.

夜吻♂芭芘 2024-11-21 11:56:09

嗯嗯嗯。

  • 如果问题是创建 Bar 很困难/麻烦,那么就让创建它们变得容易。
  • 为什么不也有一个构造函数,它具有从 Bar 对象获取的任意数量的参数?看起来像是一个包装器或 Dao 之类的东西。 可以通过使用包装器来避免 20 或 30 参数调用,但是您的调用者将如何创建包装器(不使用 20 或 30 参数)调用创建包装器或使用“返回此”设置器的 20 或 30 级链接)?

也就是说,您所说的测试是什么类型?如果要测试的东西是单独的方法,或者要测试的东西是我们可以获得的最接近生产环境的整个应用程序,那么创建环境所需的内容就会产生严重的差异对于要测试的东西。 “尽可能像生产一样”具体意味着您不应该执行任何旨在使测试成功的代码。在针对应用程序的较小单个部分的测试中,这稍微不是什么问题。 “测试”并不总是与“测试”相同。测试汽车的防滚架意味着测试它是否能够承受其声称可以承受的扭矩。测试整辆车时,您不会做同样的事情。测试零件与测试整个组件不同。

Hmmmmmm.

  • If the problem is that Bars are difficult/cumbersome to create, then make it easy to create them.
  • Why don't you have a constructor as well that has the whatever number of arguments that are taken from the Bar object ? It looks like it's a wrapper or Dao kind of thing. You can avoid the 20- or 30- arg invocations by using the wrapper, but how are your invokers going to create the wrapper (without using the 20- or 30-arg invocation for creating the wrapper or using a 20- or 30- level chaining of "return this" setters) ?

That said, what kind of tests are you speaking of ? If the thing-to-be-tested is individual methods or the thing-to-be-tested is the entire application in the most production-like setting we can get, that makes a serious difference as to what it takes to create the environment for the thing-to-be-tested. "As production-like as we can get" means specifically you should not be executing any code whose purpose is just to make the test succeed. That is somewhat less of a problem in tests targeted at smaller individual parts of the application. "Testing" is not always the same thing as "testing". Testing rollbars for cars means stuf like testing whether it can take the torque it says it can take on the tin. You don't do the same stuff when testing the entire car. Testing a part is not the same thing as testing the entire assembly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文