是否鼓励在单元测试中使用方法变量而不是类变量?

时间:2018-08-07 20:20:57

标签: java unit-testing

当在类内部编写函数以将函数与类变量解耦时,是否应该尝试使用方法2,以便可以更好地对单个函数进行单元测试?始终将类变量作为方法参数传递给类函数是一种好习惯吗?

 public class User 
 {
     public string  BirthOfMonth = string.Empty;
     public string  BirthOfDay = string.Empty;

     public MyClass(string month, string day)
     {
         this.BirthOfMonth = month;
         this.BirthOfDay = day;
     }

     // method 1
     public string GetUserBirthday() {
         return BirthOfMonth +"/" + BirthOfDay;
     }

     // method 2
     public string GetUserBirthday(string month, string day) {
         return month +"/" +day;
     }
}

在类方法中引用类成员是很常见的(如上面的方法1)?还是将这些成员作为方法参数(上面方法2中的a)传递而不是直接在方法内部使用它们总是更好?

3 个答案:

答案 0 :(得分:1)

如果将属于该类的变量传递到类似public string GetUserBirthday(string month, string day)的方法中,则可以有效地中断User类的数据和对该数据进行的操作之间的耦合。面向对象的主要思想之一不胜枚举。

您必须保留成员变量public或为字段引入getter,以便调用者可以使用它们。另一个糟糕的设计选择!此类代码还违反了Tell, Don't Ask原则,该原则指出具有数据的类应在其上工作,而不是使内部状态对外部类可用。遵循“不要问”将带来更好的封装代码,更易于重用。

您的代码变得脆弱。您无法再更改用户生日的实现方式(例如,通过将其切换为使用Date来代替月份和日期的两个单独字段),而不必触摸班级的所有呼叫者。实现细节已从Users类泄漏出去。您的代码库将高度耦合且难以修改。

关于测试:您有一个奇怪的MyClass方法。应该是构造函数吗?然后应将其称为User。该User构造函数带有生日,您可以使用该方法查询它的日期而不传递参数,那么为什么不使用它呢?这样可以带来更好的设计,并且您仍然可以轻松进行测试。

在进行测试时,您无法从外部检查预期的行为,请仔细查看代码。也许这个班变得太大了,那里藏着一个新班,想出去吗?考虑refactoring: extract class

答案 1 :(得分:0)

以下类可以更好地表示您要完成的工作(注意封装,以免暴露您的表示):

public class User
    {
        private String  birthOfMonth = "";
        private String  birthOfDay = "";

        public User(String month, String day)
        {
          this.birthOfMonth = month;
          this.birthOfDay = day;
        }

        // method 1
        public String getUserBirthday() {
          return birthOfMonth +"/" + birthOfDay;
        }
    }

然后进行测试,如下设置User

User user = new User("August","3rd");
user.getUserBirthday();
... //do actions here

答案 2 :(得分:0)

方法2至少在像这样的简单情况下会非常奇怪。

此外,以防万一您真的不熟悉Java并且不知道这一点,Java类以大写字母开头。字符串,不是字符串。变量和方法是首字符小写。 birthOfMonth不是BirthOfMonth,getUserBirthday()不是GetUserBirthday()。也许您知道这一点,但我想我会把它捏在发芽中,以防您不知道。