【问题标题】:JUnit test always fails when comparing two objects比较两个对象时,JUnit 测试总是失败
【发布时间】:2016-08-17 12:45:14
【问题描述】:

我有一个这样的测试类, 基本上这些是从 spring-data-examples 复制粘贴。

@RunWith(SpringRunner.class)
@SpringBootTest(classes = CassandraConfig.class)
public class UserRepositoryTest {


    @Autowired UserRepository repository;
    @Autowired Session session;
    User user;

    @Before
    public void setUp() {

        user = new User();
        user.setId(42L);
        user.setUsername("foobar");
        user.setFirstname("firstname");
        user.setLastname("lastname");
    }

    /**
     * Saving an object using the Cassandra Repository will create a persistent representation of the object in Cassandra.
     */
    @Test
    public void findSavedUserById() {

        user = repository.save(user);

        assertThat(repository.findOne(user.getId()), is(user));

    }

    /**
     * Cassandra can be queries by using query methods annotated with {@link @Query}.
     */
    @Test
    public void findByAnnotatedQueryMethod() {

        repository.save(user);

        assertThat(repository.findUserByIdIn(1000L), is(nullValue()));
        assertThat(repository.findUserByIdIn(42L), is(equalTo(user)));
    }

}

每次我尝试运行单元测试时, 我总是收到这些错误消息:

20:02:16.672 [DEBUG] [TestEventLogger] com.kashu.demo.UserRepositoryTest > findSavedUserById STARTED
20:02:16.867 [DEBUG] [TestEventLogger]
20:02:16.868 [DEBUG] [TestEventLogger] com.kashu.demo.UserRepositoryTest > findSavedUserById FAILED
20:02:16.868 [DEBUG] [TestEventLogger]     java.lang.AssertionError: expected:<com.kashu.demo.User@554d7139> but was:<com.kashu.demo.User@6643364a>
20:02:16.869 [DEBUG] [TestEventLogger]         at org.junit.Assert.fail(Assert.java:88)
20:02:16.869 [QUIET] [system.out] 20:02:16.868 [
20:02:16.869 [DEBUG] [TestEventLogger]         at org.junit.Assert.failNotEquals(Assert.java:834) 
20:02:16.869 [QUIET] [system.out] INFO] [org.gradle.api.internal.tasks.testing.worker.TestWorker] Gradle Test Executor 1 finished executing tests.
20:02:16.870 [DEBUG] [TestEventLogger]         at org.junit.Assert.assertEquals(Assert.java:118)
20:02:16.870 [DEBUG] [TestEventLogger]         at org.junit.Assert.assertEquals(Assert.java:144)
20:02:16.870 [DEBUG] [TestEventLogger]         at com.kashu.demo.UserRepositoryTest.findSavedUserById(UserRepositoryTest.java:67)
20:02:16.871 [DEBUG] [TestEventLogger]         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
20:02:16.871 [DEBUG] [TestEventLogger]         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
20:02:16.872 [DEBUG] [TestEventLogger]         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
20:02:16.872 [DEBUG] [TestEventLogger]         at java.lang.reflect.Method.invoke(Method.java:498)
20:02:16.872 [DEBUG] [TestEventLogger]         at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)

似乎 assertThat 抱怨要比较的 2 个用户对象不相等,所以我应该在这些代码中做些什么来成功测试吗?如果我需要比较 2 个对象之间的相等性,这里列出的测试代码是正确的解决方案吗?


[更新]

我在我的 User 实体类中添加了一个 equals() 函数,如下所示:

@Table(value = "users")
public class User {

    @PrimaryKey("user_id") private Long id;

    @Column("uname") private String username;
    @Column("fname") private String firstname;
    @Column("lname") private String lastname;

    public User(){

    }

    public User(Long id,String username,String firstname,String lastname) {
        this.id = id;
        this.username = username;
        this.firstname = firstname;
        this.lastname = lastname;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public boolean equals(Object obj){
        if (this==obj) return true;
        if (this.getClass() != obj.getClass()) return false;
        User user = (User) obj ;
           return (this.id == user.getId()) && 
                   (this.username.equals(user.getUsername())) &&
                   (this.firstname.equals(user.getFirstname())) && 
                   (this.lastname.equals(user.getLastname()));
    }



}

并尝试再次运行单元测试,但我仍然得到:

20:51:54.037 [DEBUG] [TestEventLogger] com.kashu.demo.UserRepositoryTest > findSavedUserById STARTED
20:51:54.189 [DEBUG] [TestEventLogger]
20:51:54.189 [DEBUG] [TestEventLogger] com.kashu.demo.UserRepositoryTest > findSavedUserById FAILED
20:51:54.189 [DEBUG] [TestEventLogger]     java.lang.AssertionError:
20:51:54.190 [DEBUG] [TestEventLogger]     Expected: is <com.kashu.demo.User@2fa98d0f>
20:51:54.190 [DEBUG] [TestEventLogger]          but: was <com.kashu.demo.User@44dab940>
20:51:54.190 [DEBUG] [TestEventLogger]         at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)

有什么建议吗?


[更新2]

我想我写到 equals() 函数中的逻辑可能是错误的,所以我尝试将我的用户的 equals() 函数修复为:

public boolean equals(Object obj) {
    return true;
}

它看起来很愚蠢,但我可以确定发生了什么, 在我完成这个并再次构建我的项目之后, 我看到消息: Gradle 测试运行:测试通过 所以问题实际上出在 equals() 函数中 是的,谢谢大家,你们帮了我很多! 对不起我的英语水平不好:D

【问题讨论】:

  • Userequals() 长什么样子?
  • 用户的 equals() 函数完全空白...是这个原因吗?
  • 大胆猜测。
  • 你实现equals后还有报错吗?
  • 这个问题是一个完美的例子,为什么不应该依赖equals 方法进行测试。 shazamcrest 等工具可以帮助您解决此类问题。

标签: java spring unit-testing junit spring-data-cassandra


【解决方案1】:

任何体面的 IDE 都可以为您生成 equals 方法;基于要用于相等比较的字段。所以,不要手动写那些东西。让工具为您完成工作。

然后:请记住,在覆盖 equals() 时,您还应该覆盖 hashCode()!

最后:你在这里做的是一个“滴滴涕”的例子(我的意思见下图来自Geek&Poke)。

您不应该在生产代码中添加 equals 方法,因为您的测试失败了。如果您希望您的代码拥有自己的 equals 方法,那么您的测试应该会失败!我要说的是:不要添加功能来使测试通过(好吧,除非您编写该测试以提醒您实现某个功能)。取而代之的是:决定您希望产品中的哪些功能,然后相应地编写测试。

只是为了好玩:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多