比较两个对象时,JUnit测试始终失败

时间:2016-08-17 12:45:14

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

我有一个这样的测试类, 基本上这些是来自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)

似乎断言抱怨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)

有什么建议吗?

[UPDATE2]

我想也许我写入equals()函数的逻辑是错误的,所以我尝试修改我的User的equals()函数:

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

看起来非常愚蠢,但我可以确保发生了什么, 在我完成这个并再次构建我的项目之后 我看到了消息: Gradle Test Run:test PASSED 所以问题实际上是在equals()函数中 呀,谢谢大家,你帮了我很多忙! 对不起我的英语能力差:D

1 个答案:

答案 0 :(得分:0)

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

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

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

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

只是为了它的乐趣:DDT