[英]NHibernate fluent HasMany testing with PersistenceSpecification
[英]Fluent NHibernate PersistenceSpecification CheckList
我目前正在研究一個我們使用 Fluent NHibernate 的大學項目。 我正在研究如何為我們的實體和 Fluent 映射創建測試。
然而,我在試圖弄清楚如何使用 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 屬性。
有任何想法嗎?
最好的問候,肯尼斯,丹麥
我認為 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();
}
CheckList 似乎有一個錯誤。 盡管您的映射是正確的,但它會嘗試在持久化父級之前持久化子級。 如果您改用 CheckComponentList,您的 Item 將在 ItemPictures 之前被持久化,並且您的測試應該通過。
您不能需要覆蓋 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();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.