4

私は現在、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 プロパティを設定する方法が本当にわかりません。

何か案は?

敬具、ケネス、デンマーク

4

3 に答える 3

4

ItemPictureに対してテストを実行する前に、ItemPictureがDBに存在している必要があると思います(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();
}
于 2010-11-24T11:42:25.973 に答える
3

チェックリストにはバグがあるようです。マッピングは正しいですが、親を永続化する前に子を永続化しようとします。代わりにCheckComponentListを使用すると、ItemPicturesの前にアイテムが永続化され、テストに合格するはずです。

于 2011-07-18T13:15:32.030 に答える
1

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();
    }
}
于 2009-11-29T23:24:38.407 に答える