我目前正在做一个大学项目,在这个项目中我们使用了Fluent NHibernate。我正在研究如何为我们的实体和流畅的映射创建测试。
然而,当我试图弄清楚如何使用PersistenceSpecification的CheckList时,我走进了死胡同。
单元测试失败,错误如下:
MvcShop.Core.Tests.EntitiesTests.ItemTest.CanMapItem threw exception: NHibernate.PropertyValueException: not-null property references a null or transient valueMvcShop.Core.Entities.ItemPicture.Item.测试定义为:
private IList<ItemPicture> _itemPictures = new List<ItemPicture>()
{
new ItemPicture { Filename = "test.jpg", Title = "Test title", PrimaryPicture = true},
new ItemPicture { Filename = "test2.jpg", Title = "Test title 2" }
};
[TestMethod]
public void CanMapItem()
{
new PersistenceSpecification<Item>(Session)
.CheckProperty(i => i.Title, "Test item")
.CheckProperty(i => i.Description, "Test description")
.CheckProperty(i => i.SalesPrice, (decimal)0.0)
.CheckList(i => i.ItemPictures, _itemPictures) // Complains that Item on ItemPicture is null.
.VerifyTheMappings();
}我的映射定义为:
public ItemMap()
{
Table("Item");
Id(i => i.ItemID).GeneratedBy.Identity().Column("Item_id");
Map(i => i.ItemNo).Nullable().Length(30);
Map(i => i.Title).Not.Nullable().Length(250);
Map(i => i.Description).Nullable();
Map(i => i.SalesPrice).Not.Nullable().Precision(18);
Map(i => i.AverageRating).Precision(18).Nullable();
Map(i => i.Visible).Not.Nullable();
Map(i => i.Weight).Not.Nullable().Precision(18);
Map(i => i.TimesPurchased);
Map(i => i.InStock).Not.Nullable();
Map(i => i.DateAdded).Not.Nullable();
HasManyToMany(i => i.ItemCategories).Cascade.All().Inverse().Table("ItemCategoryItem");
HasMany(i => i.ItemPictures).Cascade.AllDeleteOrphan().Inverse().LazyLoad();
HasMany(i => i.Comments).Cascade.AllDeleteOrphan().Inverse().LazyLoad();
HasMany(i => i.Ratings).Inverse().LazyLoad();
}
public ItemPictureMap()
{
Table("ItemPicture");
Id(i => i.ItemPictureID).GeneratedBy.Identity().Column("ItemPicture_id");
Map(i => i.Title).Nullable();
Map(i => i.Filename).Not.Nullable();
Map(i => i.PrimaryPicture).Not.Nullable();
References(i => i.Item).Not.Nullable().Column("Item_id");
}在使用PersistenceSpecification类时,我真的不知道如何填充ItemPicture的Item属性。
有什么想法吗?
最好的问候,肯尼斯,丹麦
发布于 2010-11-24 19:42:26
我认为在对其运行测试之前,ItemPicture必须存在于数据库中(根据Fluent文档:https://github.com/FluentNHibernate/fluent-nhibernate/wiki/persistence-specification-testing -请参阅该页面的最后一行)。
尝试:
[TestMethod]
public void CanMapItem()
{
var p1 = new ItemPicture { Filename = "test.jpg", Title = "Test title", PrimaryPicture = true};
var p2 = new ItemPicture { Filename = "test2.jpg", Title = "Test title 2" };
using (var tx = Session.BeginTransaction())
{
Session.Save(p1);
Session.Save(p2);
};
new PersistenceSpecification<Item>(Session)
.CheckProperty(i => i.Title, "Test item")
.CheckProperty(i => i.Description, "Test description")
.CheckProperty(i => i.SalesPrice, (decimal)0.0)
.CheckList(i => i.ItemPictures, new List<ItemPicture> {p1, p2});
.VerifyTheMappings();
}发布于 2011-07-18 21:15:32
CheckList似乎有一个bug。尽管您的映射是正确的,但它将尝试在持久化父级之前持久化子对象。如果你改用CheckComponentList,你的项目将在ItemPictures之前被销毁,你的测试应该会通过。
发布于 2009-11-30 07:24:38
你不能,你需要重写GetHashCode和Equals并创建你自己的IEqualityComparer。这样做的原因是实体在默认情况下不能比较,而值对象可以。
例如,默认情况下不能比较DateTime,原因很简单,它们不是一个值,它们是一个具有值的实例,并且存在datetime1 != datetime2,即使它们的日期完全相同,所以您需要做的是在键值上比较它们。对于像上面这样的类。我假设Item包含一堆ItemPictures,然后在IEqualityComparer实现中,当您重写equals时,您应该检查当前对象是否为ItemPicture类型,如果是,则检查当前ItemPicture的id是否与其他两端的ItemPicture.Id匹配。由于代码胜于雄辩,我将给你一个小例子:
[TestMethod]
public void CanMapItem()
{
new PersistenceSpecification<Item>(Session, new CustomIEqualityComparer())
.CheckProperty(i => i.Title, "Test item")
.CheckProperty(i => i.Description, "Test description")
.CheckProperty(i => i.SalesPrice, (decimal)0.0)
.CheckList(i => i.ItemPictures, _itemPictures) // Complains that Item on ItemPicture is null.
.VerifyTheMappings();
}
public class CustomIEqualityComparer: IEqualityComparer
{
public bool Equals(object x, object y)
{
if (x == null || y == null)
{
return false;
}
if (x is ItemPicture && y is ItemPicture)
{
return ((ItemPicture) x).Id == ((ItemPicture) y).Id;
}
if(x is DateTime && y is DateTime)
{
return ((DateTime)x).Year ==((DateTime)y).Year;
}
return x.Equals(y);
}
public int GetHashCode(object obj)
{
throw new NotImplementedException();
}
}https://stackoverflow.com/questions/1816531
复制相似问题