【发布时间】:2016-03-29 20:16:44
【问题描述】:
这是一个从现实生活中剥离出来的方法......真正的方法做其他事情,但我已经将一些奇怪的行为缩小到这几行。考虑一种尝试从java.util.Date... 创建java.sql.Timestamp 的方法(不要介意我在此方法中做错了什么;这不是重点):
public class MyTest {
public Timestamp convertDateToTimestamp(Date d) {
long l = d.getTime();
Timestamp ts = new Timestamp(l);
return ts;
}
}
所以我为此方法编写了以下 JMockit JUnit 测试用例:
@RunWith(JMockit.class)
public class MyTestTest {
@Tested MyTest test;
@Test
public void testConvertDateToTimestamp(@Mocked final Timestamp ts, @Mocked final Date d) throws Exception {
new Expectations() {
{
d.getTime(); result = 8675309l;
new Timestamp(8675309l); result = ts;
}
};
Timestamp retval = test.convertDateToTimestamp(d);
assertThat(retval, sameInstance(ts));
}
}
注意最后一行的断言...我想我应该确定我得到的实例与我的构造函数创建的实例完全相同。
这个测试返回一个非常奇特的结果:
java.lang.AssertionError:
Expected: sameInstance(<java.sql.Timestamp@6e3c1e69>)
but: was <java.sql.Timestamp@6e3c1e69>
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at com.example.dcohl.MyTestTest.testConvertDateToTimestamp(MyTestTest.java:32)
...
谁能解释一下?我的断言失败了,因为它期待Timestamp 的一个实例,但它却得到了......与Timestamp 完全相同的实例?
现在,如果我检查是否相等,使用is(ts) 而不是sameInstance(ts),我的测试就会成功。是否是同一个对象并不重要;平等就足够了。但这是一个令人头疼的结果......
【问题讨论】:
-
通过使用调试器可以看到
retval和ts是两个不同的对象,尽管toString方法为两者生成相同的字符串。
标签: java junit jmockit hamcrest