我有以下情况。我想将设置创建日期的责任委托给DAO对象。
Class Product{
//other fields
Date creationDate;
}
Class ProductDAO{
private GenericDAO dao;
public void create(Product p){
p.setCreationDate(new Date());
dao.create(p);
}
}
Class Main{
private ProductDAO productDAO;
public void createProduct(){
Product p = new Product();
productDAO.create(p);
LOG.debug(p.getCreationDate());
}
}
上述方法似乎正确吗?我应该退回更新的产品吗? 来自ProductDAO类的create方法而不是依赖的对象 副作用?
Product create(Product p){
p.setCreationDate(new Date());
dao.create(p);
return p;
}
或者在Main类中,我应该在之后从数据库中读取对象 创建而不是依赖于返回对象或副作用 createProduct方法?在这种情况下,唯一的事情就是增加额外呼叫的开销。
public void createProduct(){
Product p = new Product();
productDAO.create(p);
p = productDAO.read(p.getId());
LOG.debug(p.getCreationDate());
}
很抱歉。我希望我能解释一下。
答案 0 :(得分:1)
我认为一个非常有效的方法是创建一个具有creationDate“set”的Product实例,并让你的mockProductDao返回。
Date timeStamp = new Date();
Product productWithCreationDate = new Product();
productWithCreationDate.setCreationDate(timeStamp);
when(mockProductDao.create(anyObject()).thenReturn(productWithCreationDate);
我认为您不需要从ProductDAO返回p,因为您调用productDAO.create(p)的任何地方,然后您可以在下一个地方访问p
(with creationDate) line - 对吗?
如果你不信任DAO层,你只需要从DAO读回p
:)所以,鉴于你确信DAO层会抛出正确的异常{{1 }}方法失败,我认为您不需要再次重新阅读create()
。
答案 1 :(得分:1)
测试日期是否设置的一种方法是使用argThat。您需要执行类似
的操作@Test
public void shouldSetCreationDateAtProductWhenCreatingIt() {
// given
Product product = mock(Product.class);
// when
dao.create(product);
// then
verify(product).setCreationDate(argThat(is(not(nullValue(Date.class)))));
}
因此,我只做了一个简单的验证,Product#setCreationDate(Date)
被调用非空值Date
。您可以创建自定义匹配器以查看Date
对象是否是您期望的对象。这只是为了测试班级ProductDao
。
如果要以模拟getCreationDate返回的方式对单元测试Main
进行单元测试,可以向ProductDao#create
添加一个返回值,使其返回持久化对象。
public class ProductDao {
public Product create(Product p){
p.setCreationDate(new Date());
dao.create(p);
return p;
}
}
然后你可以在你的Main类中模拟productDao的返回
@Test
public void shouldUseReturnedProductFromDaoToLog() {
// given
Product product = mock(Product.class);
Date creationDate = new Date();
given(product.getCreationDate()).willReturn(creationDate);
given(dao.create(any(Product.class)).willReturn(product);
// when
Product createdProduct = main.createProduct();
// then
assertThat(createdProduct, is(equalTo(product)));
}
我添加了一个返回到createProduct,因为我想测试它是否与DAO返回的相同。然后我们将单元测试分开,看看ProductDao
是否从Main
做了预期(设置creationDate)(创建产品并将其保存在Dao中)
希望这有帮助。
答案 2 :(得分:0)
为什么需要通过setter分配创建Date
?只需在构造函数中指定Date
:
Product p = new Product(); //here you set creation date
productDAO.create(p);