我有一个这样的测试类, 基本上这些是来自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
答案 0 :(得分:0)
任何体面的IDE都可以生成等于你的方法;基于您希望用于等于比较的字段。所以,不要手动写出那些东西。让工具为您完成工作。
然后:请记住,当覆盖equals()时,您还应该覆盖hashCode()!
最后:你在这里做的是一个“滴滴涕”的例子(见Geek&Poke下面的图片,我的意思)。
您不应该在生产代码中添加equals方法,因为您的测试失败了。如果您希望您的代码拥有自己的equals方法,那么您的测试应该会失败!我所说的是:不添加功能以使测试通过(好吧,除非你编写该测试以提醒你实现某个功能)。相反:决定产品中需要哪些功能,然后相应地编写测试。