4

ObjectContext からすべての EntityObjects を削除するための次の汎用拡張メソッドがあります。

public static void DeleleAllObjects<TEntity>(this ObjectContext context)
        where TEntity : EntityObject
    {
        var objectSet = context.CreateObjectSet<TEntity>();
        objectSet.ToList().ForEach(e => objectSet.DeleteObject(e));
    }

私はTDDにかなり慣れておらず、nUnit/Moqを使用しています...しかし、このメソッドのテストをどこに書くべきかわかりませんか?

4

1 に答える 1

5

これが役立つことを願っています:

[TestFixture]
public class ExtensionTest
{
    public class FakeEntity : EntityObject
    {

    }

    [Test]
    public void DeleteAllObjects()
    {
        //arrange
        var objectsToDelete = new List<FakeEntity>
            {
                new FakeEntity(),
                new FakeEntity()
            };
        var mockContext = new Mock<ObjectContext>();
        var mockObjectSet = new Mock<ObjectSet<FakeEntity>>();
        mockObjectSet.Setup(x => x.ToList()).Returns(objectsToDelete);
        mockContext.Setup(x => x.CreateObjectSet<FakeEntity>()).Returns(mockObjectSet.Object);

        //act
        mockContext.Object.DeleteAllObjects<FakeEntity>();

        //assert
        mockContext.Verify(x => x.CreateObjectSet<FakeEntity>(), Times.Once());
        mockObjectSet.Verify(x => x.ToList(), Times.Once());
        mockObjectSet.Verify(x => x.DeleteObject(It.IsAny<FakeEntity>()), Times.Exactly(2));

    }
}

ここで、これは、モック化されたすべての型 (コンテキストとオブジェクト セット) に、呼び出すメソッドが として宣言されているvirtualか、クラスが であると仮定していますabstract。通常、インターフェイスをモックすることで制限が緩和されます。

また、アサーションでさらにうるさいようにして、実際DeleteObjectに最初のインスタンスで最初に呼び出され、次に 2 番目のインスタンスで呼び出され、最初のインスタンスで 2 回呼び出されないようにする場合は、テストのその部分を変更できます。しかし、これはかなり良い出発点として役立つはずです。

要約する:

この特定のテストは、拡張メソッド内のコードのみを実際にテストする必要があります。CreateObjectSet<>()つまり、 を呼び出し、リストを取得してから、それぞれを呼び出すことだけを保証する必要がありますDeleteObject

DeleteObject()実際に the が変更されているかどうかはまったく気にする必要はありませObjectSetん (実際には変更されません。これはモックであるためです)。それはメソッドのテストの責任であるべきDeleteObject()ですが、実際には EF メソッドであると想定しているため、サード パーティ コンポーネントのテストを作成するべきではありません。

于 2012-12-20T07:30:21.137 に答える