【问题标题】:JUnit tests for POJOsPOJO 的 JUnit 测试
【发布时间】:2010-10-15 00:51:29
【问题描述】:

我在一个项目中工作,我们必须为所有简单的 bean (POJO) 创建单元测试。如果 POJO 只包含 getter 和 setter,那么为它们创建单元测试有什么意义吗?假设 POJO 将在大约 100% 的时间内工作是否安全?


重复 - Should @Entity Pojos be tested?

另请参阅

Is it bad practice to run tests on a DB instead of on fake repositories?

Is there a Java unit-test framework that auto-tests getters and setters?

【问题讨论】:

标签: java junit pojo


【解决方案1】:

POJO 还可能包含其他函数,例如 equals()、hashCode()、compareTo() 和各种其他函数。了解这些功能是否正常工作可能很有用。

【讨论】:

  • 这些也是我倾向于用 POJO 测试的东西。不是访问器,而是 equals 和 hashCode 以及它们在不同上下文中的行为方式,例如如果 equals 的参数是 Hibernate 代理等,它们仍然有效吗?
  • 如果它有逻辑那么它不是 POJO,它们只是模型
【解决方案2】:

我认为测试简单的属性获取器和设置器没有意义。单元测试的重点不是验证您的编译器是否工作。

但是,一旦您向 getter 和 setter(或其他方法)添加条件、空检查或其他重要行为,我认为添加单元测试是合适的。

【讨论】:

    【解决方案3】:

    我认为如果 getter 和 setter 是使用 IDE 创建的,那么应该没问题。我们还有其他东西可以放入我们的代码。显然,您将测试 POJO 的序列化/反序列化。

    【讨论】:

    • 为什么?我们在测试序列化机制吗?除非您自定义了序列化,否则这将是一种浪费。
    【解决方案4】:

    我的回答是,琐碎的 getter 和 setter 不值得自己测试。如果我添加除了简单读取或写入之外的任何代码,那么我会添加测试。

    当然,这都是样板文件,因此您可以轻松编写一个脚本,为您的 getter 和 setter 生成单元测试,如果您认为那里有任何价值的话。某些 IDE 可能允许您定义一个模板,该模板使用为该样板代码填充的测试方法创建测试用例(我在此考虑 IntelliJ,但 Eclipse 可能也可以处理它,尽管我还没有做过类似的事情) IDE)。

    【讨论】:

      【解决方案5】:

      根据我的经验,只使用 getter 和 setter 为 POJO 创建单元测试是有点过头了。当然,也有一些例外,如果 getter/setter 中有额外的逻辑,比如检查 null 和做一些特殊的事情,那么我会为此创建一个单元测试。

      另外,如果 POJO 中有错误,我会为它创建一个单元测试,这样我们就可以防止它再次发生。

      【讨论】:

        【解决方案6】:

        可能值得做一个简单的测试来确保你没有写过

        public void setX(int x) {
           x = x;
        }
        

        尽管您应该编写代码以避免这种情况(通过在方法参数上放置final 修饰符,或类似的)。这还取决于您生成访问器的方式,以及它们是否会遭受复制/粘贴错误等问题(即使在尝试强制使用 IDE 的环境中也会发生这种情况 - 它只是会发生)。

        然而,我对包含大量 setter/getter 的类的主要关注是,类在做什么?对象应该为您做事,而不仅仅是保存和返回数据。如果这些是数据实体对象,那么 setter/getter 模式可能是正确的。然而更好的模式是在对象中设置数据,并要求对象用它做一些事情(计算你的银行余额,发射火箭等),而不是返回数据让你自己做!

        【讨论】:

          【解决方案7】:

          你想知道的单元测试代码是有效的(当然对于测试的情况)。不要对您只想确保有效的代码进行单元测试。

          我想不出太多我只想确定的事情。

          【讨论】:

            【解决方案8】:

            TDD 中的规则是"Test everything that could possibly break" getter 可以破解吗?一般不会,所以我懒得去测试它。此外,我测试的代码肯定会调用getter,所以它被测试。

            我的个人规则是,我将为任何做出决定或做出不只是微不足道的计算的函数编写一个测试。我不会为i+1 编写测试,但我可能会为if (i<0)... 编写测试,并且肯定会为(-b + Math.sqrt(b*b - 4*a*c))/(2*a) 编写测试。

            顺便说一句,对 POJO 的强调背后有不同的原因。我们希望将大量代码写入 POJO,不依赖于它们运行的​​环境。例如,很难测试 servlet,因为它们依赖于在容器中执行。因此,我们希望 servlet 调用不依赖于其环境并因此易于测试的 POJO。

            【讨论】:

            • 如果您所在的公司坚持代码覆盖率,您可以使用 Apache commons 的 BeanUtils 创建一个通用的 getter/setter 测试。只需将类传递给它,获取所有 getter 和 setter 方法,使用一点方法名称比较来匹配它们。
            • 将来有人可能会在你的 getter / setter 中添加一些逻辑而忘记调整测试,除非它们失败
            • 这就是 lombok[projectlombok.org/] 派上用场
            【解决方案9】:

            我曾经因为这样的事情花了两个小时:

            int getX()
            {
                return (x);
            }
            
            int getY()
            {
                return (x); // oops
            }
            

            因为为简单的 getter 编写测试几乎不需要时间,所以我现在这样做是出于习惯。

            【讨论】:

            【解决方案10】:

            我正在尝试使用 cobatura 进行代码覆盖,但遇到了同样的问题。

            最好有一个注释添加到类中,它说不要将此类包含在代码覆盖范围内。但是,可以将您的 pojo 放在一个单独的包中,然后将该包从分析中排除。

            根据您的工具查看文档,它适用于 Ant、Maven 或命令行。

            【讨论】:

              【解决方案11】:

              我使用 IntelliJ 作为 IDE,它几乎为我编写了琐碎的 POJO——当然是构造函数和 getter/settors。我认为单元测试没有任何意义,因为任何错误很可能出现在我编写的测试代码中。

              【讨论】:

                【解决方案12】:

                我刚刚开始了一个项目来做这件事。它现在处于 pre-alpha 阶段。它是一个 Eclipse 插件。

                虽然我同意通常 POJO setter/getter 不一定需要测试,但我相信在那里进行简单测试会很好,因为随着时间的推移,事情会发生变化,这将使您更容易添加更多测试对于 POJO 的。设置了单元测试,测试setter/getter的方法在那里,你所要做的就是处理新的复杂性。

                这也有助于生成代码覆盖率报告,这有助于让管理人员满意。 (我的公司使用艾玛)。

                https://sourceforge.net/projects/unittestgplugin/

                【讨论】:

                  【解决方案13】:

                  单元测试不仅验证代码是否正常工作,而且还记录了预期的行为。我不知道有多少次我看到事情中断了,因为一段时间后,有人改变了 POJO 中的 getter 或 setter 的行为,然后它意外地破坏了其他东西(例如,有人向 setter 添加了逻辑如果有人在字符串上设置空值,setter 会将其更改为空字符串,这样 NPE 就不会发生)。

                  我不认为对数据存储 POJO 进行单元测试是浪费时间,我认为它们是未来维护的安全网。话虽这么说,如果您手动编写测试来验证这些对象,那么您将很难做到。看看http://gtcgroup.com/testutil.html之类的东西

                  【讨论】:

                    【解决方案14】:

                    有一个开源实用程序http://meanbean.sourceforge.net/ 允许您测试 POJO。还有一个页面描述了一个人可能对这个实用程序提供什么以及为什么应该使用它的优点/问题。

                    我自己(还)从来没有累过它,但它已被推荐给我。

                    【讨论】:

                    • 这个库在没有无参数构造函数的情况下不能与 POJO 一起使用
                    • 这听起来不对。所有示例等都使用带有无参数构造函数的 Java Bean(并且许多 Java bean 将具有无参数构造函数。究竟是什么不起作用?
                    • 因此,如果有类具有带参数的构造函数并且没有显式的无参数构造函数。在这种情况下,使用这个库会抛出异常。
                    • 好的,很高兴知道。我应该在我之前的评论中说 POJO 而不是 Java Beans。 Java Beans 根据定义需要一个无参数构造器
                    【解决方案15】:

                    恕我直言 POJO 在测试任何功能的逻辑时会自动测试,例如为了测试任何函数,我们可能需要注入/模拟某些值,POJO 和 POJO 的 getter/setter 是间接测试的。

                    但是对于特定用例来消除用于单元测试的 POJO,可以通过以下两种方式实现:

                    1. 使用库:使用有助于测试 POJO 的现有库。我遇到的一个这样的库是 meanbean。

                      参考http://meanbean.sourceforge.net/

                      Mavenhttp://mvnrepository.com/artifact/org.meanbean/meanbean(当前版本:2.0.3)

                    2. 忽略 POJO:Sonar 可以配置为排除 POJO 或要从单元测试覆盖率报告中排除的特定包。下面的几个例子:

                      <properties>
                          <sonar.coverage.exclusions>
                              **/domain/**/*,
                              **/pojos/*
                          </sonar.coverage.exclusions>
                      </properties>
                      

                    【讨论】:

                    • 这个答案似乎不完整,你想在那之后添加一些东西吗?
                    【解决方案16】:

                    这个问题可以通过使用 Lombok 库来解决,该库消除了所有这些样板代码以及等号和哈希码。

                    所以你不需要测试它们,除非你对等号和哈希码有特定要求

                    https://projectlombok.org/

                    【讨论】:

                      【解决方案17】:

                      MeanBean 库提供了一个 API 来测试 POJO。例如下面的 sn -p 测试是否 Emplooyee pojo。演示应用link.

                      BeanTester beanTester = new BeanTester();
                      beanTester.testBean(Employee.class);
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2022-12-18
                        • 1970-01-01
                        • 1970-01-01
                        • 2018-03-23
                        • 1970-01-01
                        • 2023-04-08
                        • 2010-11-10
                        • 2016-08-21
                        相关资源
                        最近更新 更多