单元测试 - 实现等于仅便于测试

foe*_*ens 7 java junit unit-testing equals

以下是我对单元测试的要求:

  1. 我想对我的生产课进行单元测试
  2. 我想将测试代码和生产代码分开,以便我只能发布生产代码

这似乎是合理的要求.但是,当我需要使用诸如assertEqualson对象之类的方法时,总会出现问题,因为这些equals方法需要覆盖该方法.该equals方法必须在生产类中实现,但实际上仅用于测试.如果良好的编码实践规定如果equals被覆盖,那么这将变得更加糟糕,然后hashCode也应该实施,从而导致更多未使用的生产代码使生产类混乱.

这是一个User模型的简单示例(IntelliJ自动实现equalshashCode)

public class User
{
    public long id;
    public long companyId;
    public String name;
    public String email;
    public long version;

    @Override
    public boolean equals(Object o)
    {
        if(this == o) return true;
        if(o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        if(companyId != user.companyId) return false;
        if(id != user.id) return false;
        if(version != user.version) return false;
        if(!email.equals(user.email)) return false;
        if(!name.equals(user.name)) return false;
        return true;
    }

    @Override
    public int hashCode()
    {
        int result = (int) (id ^ (id >>> 32));
        result = 31 * result + (int) (companyId ^ (companyId >>> 32));
        result = 31 * result + name.hashCode();
        result = 31 * result + email.hashCode();
        result = 31 * result + (int) (version ^ (version >>> 32));
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

由于可以看出,equalshashCode占用了大量的空间和杂波的类.

该问题的一个解决方案可以是创建一个类,该类UserTester可以具有assertUserEquals可以用于代替例如的方法.JUnit的assertEquals.

另一个解决方案可能是创建一个UserComparator.但是,似乎JUnit没有任何assertEquals需要的东西Comparator.

关于这一点,最佳做法是什么?

Jk1*_*Jk1 1

Uniutils有一个完美的反射 equals 方法,可用于单元测试。这样,您的生产代码就可以从所有这些测试内容中保持清晰。

public class User { 

    private long id; 
    private String first; 
    private String last; 

    public User(long id, String first, String last) { 
        this.id = id; 
        this.first = first; 
        this.last = last; 
    } 
}
Run Code Online (Sandbox Code Playgroud)

后来在测试中:

User user1 = new User(1, "John", "Doe"); 
User user2 = new User(1, "John", "Doe"); 
assertReflectionEquals(user1, user2);
Run Code Online (Sandbox Code Playgroud)

如果你使用 Mockito,它有自己的方法来做同样的事情:

Mockito.verify(userDeleter).delete(Mockito.refEq(user));
Run Code Online (Sandbox Code Playgroud)