Groovy for Java 代码中的单元测试 - 如何模拟 Java 类?

发布于 2024-10-21 13:31:43 字数 549 浏览 2 评论 0原文

我将在一个用 Java 编写的大型项目中介绍 Groovy,首先(像大多数人一样)在 Groovy 中为 Java 类编写单元测试。

所以我遇到的问题是:

假设我有 2 个 Java 类,ClassA 和 ClassB,以这种方式交互:

public class ClassA {
  public void doSomething(...) {

    ...//something

    ClassB.invokeSomeStaticMethod((someParam);

    ...//something

  }
}

ClassB 是从数据库查找一些数据的服务。我正在测试 A 类功能。所以我想以某种方式模拟 ClassB,所以它是我的单元测试上下文中的 invokeSomeStaticMethod() 将返回模拟值进行测试。据我了解,这里的主要问题是这两个类都是Java,因此ClassB.invoke...方法不是通过Groovy MOP(Groovy Mocks 所基于的)路由的。我说得对吗?我怎样才能实现我所需要的?

谢谢! 米哈伊尔

I'm introducing Groovy in a large project written in Java, starting (as most of guys do) with writing unit test in Groovy for Java classes.

So the problem I have is:

Imagine I have 2 Java classes, ClassA and ClassB, interacting this way:

public class ClassA {
  public void doSomething(...) {

    ...//something

    ClassB.invokeSomeStaticMethod((someParam);

    ...//something

  }
}

ClassB is service looking up some data from database. I'm testing ClassA functionality. So I would like to mock ClassB somehow, so it's invokeSomeStaticMethod() in the context of my unit test
would return mocked value for testing. As far as I understand the main problem here is that both classes are Java and hence ClassB.invoke... method is not routed thru Groovy MOP, which the Groovy Mocks are based on. Am I right? And how could I achieve what I need?

Thanks!
Mikhail

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

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

发布评论

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

评论(3

Bonjour°[大白 2024-10-28 13:31:43

静态方法,就像单例一样,是可测试性的死亡。虽然在像 Groovy 这样的动态语言中情况不太如此,但当然,您已经遇到了一个典型的可测试性问题。

解决方案是外部化您的依赖项,并从 ClassB 中删除静态方法。

public class ClassA(ClassB classB)
{
    ClassB classB
    public void doSomething()
    {
         classB.invokeSomething();
    }
}

这种方法有两个好处:

  • ClassA 不再与 ClassB 紧密耦合。它可以替换为子类或模拟。
  • ClassA 现在向全世界宣传它对 ClassB 的依赖,而不是依靠运行时错误让开发人员知道缺少某些内容。

这篇优秀的文章单身人士都是骗子< /a>(来自 Google 测试博客)在探索这个概念方面做得非常出色。

Static methods, like singletons, are death to testability. While this is a little less so in dynamic languages like Groovy, certinaly here, you've struck a classic testability issue.

The solution is to externalize your dependency, and remove the static method from ClassB

public class ClassA(ClassB classB)
{
    ClassB classB
    public void doSomething()
    {
         classB.invokeSomething();
    }
}

This approach has two benenfits:

  • ClassA is nolonger tightly coupled to ClassB. It can be replaced with a subclass, or a mock.
  • ClassA now advertises it's dependency on ClassB for the world to know, rather that relying on runtime errors to let developers know that something is missing.

The excellent article Singletons are Liars (from the Google Testing blog) does an excellent job of exploring this concept.

破晓 2024-10-28 13:31:43

AFAIK,Groovy MOP 将无法替换对 ClassB.invokeSomeStaticMethod(someParam) 的调用。您可以使用 JMockit 之类的框架来帮助您模拟静态方法。

AFAIK, Groovy MOP won't be able to replace the call to ClassB.invokeSomeStaticMethod(someParam). You can use a framework like JMockit to help you mock the static method.

把回忆走一遍 2024-10-28 13:31:43

好吧,我虽然元编程可能会有所帮助,但是一旦从 Java 代码中调用 ClassB,它的元类将无法工作。

Groovy 中不带参数的模拟静态方法

Well, I though meta-programming might help, but once ClassB is called from Java code its metaClass won't work.

Mock static method with no parameters in Groovy

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