1

Moqを使用して、DetachedCriteriaクラスを使用するリポジトリのメソッドを単体テストしようとしました。しかし、内部に構築されている内部のCriteriaオブジェクトを実際にモックできないという問題に直面します。切り離された基準をモックする方法はありますか?

試験方法

        [Test]
        [Category("UnitTest")]
        public void FindByNameSuccessTest()
        {          
            //Mock hibernate here
            var sessionMock = new Mock<ISession>();
            var sessionManager = new Mock<ISessionManager>();
            var queryMock = new Mock<IQuery>();
            var criteria = new Mock<ICriteria>();
            var sessionIMock = new Mock<NHibernate.Engine.ISessionImplementor>();

            var expectedRestriction = new Restriction {Id = 1, Name="Test"};

            //Set up expected returns
            sessionManager.Setup(m => m.OpenSession()).Returns(sessionMock.Object);
            sessionMock.Setup(x => x.GetSessionImplementation()).Returns(sessionIMock.Object);

            queryMock.Setup(x => x.UniqueResult<SopRestriction>()).Returns(expectedRestriction);

            criteria.Setup(x => x.UniqueResult()).Returns(expectedRestriction);

            //Build repository            
            var rep = new TestRepository(sessionManager.Object);

            //Call repostitory here to get list
            var returnR = rep.FindByName("Test");


            Assert.That(returnR.Id == expectedRestriction.Id);
        }

リポジトリクラス

public class TestRepository
{
    protected readonly ISessionManager SessionManager;

    public virtual ISession Session
    {
        get { return SessionManager.OpenSession(); }
    }

    public TestRepository(ISessionManager sessionManager)
    {
    }


    public SopRestriction FindByName(string name)
    {

        var criteria = DetachedCriteria.For<Restriction>().Add<Restriction>(x => x.Name == name)
        return criteria.GetExecutableCriteria(Session).UniqueResult<T>();
    }

}

ここでも「NHibernate.LambdaExtensions」と「Castle.Facilities.NHibernateIntegration」を使用していることに注意してください。どんな助けでもありがたいです。

基本的に、返されたオブジェクトのアサートでnull参照例外が発生します。したがって、私は基準を正しく接続していないと思います。しかし、基準は私のリポジトリ内に作成された分離基準のプライベートフィールドであるため、これを行うことはできないと思います。

4

2 に答える 2

5

正直なところ、私はずっと前にデータベースに触れるものすべてを単体テストしようとすることをあきらめました。

インメモリ Sqlite db をスピンアップして実際のテストを実行する方がはるかに簡単です。または、実際のデータベースに対してそれらを実行したい場合は、ソース管理にチェックインするときにのみ実行される統合テストにそれらを移動します。

于 2010-06-11T14:21:33.060 に答える
1

この状況でモックを使用するポイントを見逃していると思います。モックしたいのはメソッドです

public SopRestriction FindByName(string name)
{
    ...
}

したがって、任意の型を返すことができ、SopRestrictionNHibernate を照会しているという事実について心配する必要はありません。

価値を得ることができないため、あらゆるタイプのデータコンテキストをモックすることは無意味です。

これを行う最も簡単な方法は、ITestRepository のように TestRepository からインターフェイスを抽出し、残りの依存関係グラフを ITestRepository に依存させることです。これにより、単体テストでリポジトリ自体を簡単にモックできます。

フォローアップ:リポジトリ内のメソッド呼び出しを検証したいというあなたの回答については、NHibernate 固有の使用法をすべて、NHibernate 固有のパラメーターまたは戻り値の型を持たないメソッド自体にラップすることをお勧めします。それらの方法を使用して、それらが機能することを期待してください。これが、この段階では単体テストの価値が低い理由です。あまり得られないからです。あなたが言ったことで、私はそれらをまったく嘲笑しませんが、データベースに触れるか、必要なことを行う完全な「統合」テストにします。TDD の純粋主義者が統合テストだと言ったとしても、私はこれらをまだ単体テストだと考えています。

于 2010-06-11T16:50:53.250 に答える