我有以下通用扩展方法,用于从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的新手......但是我不确定在哪里为这种方法编写测试?
答案 0 :(得分: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
,然后用第二个实例调用CreateObjectSet<>()
,而不是在第一个实例上调用两次,那么你可以改变它部分测试。但这应该是一个很好的起点。
总结:
此特定测试应该只测试扩展方法中的代码。这意味着,它应该只确保您调用DeleteObject
,获取列表,然后在每个列表上调用DeleteObject()
。
如果确实ObjectSet
确实改变了DeleteObject()
,那么它根本不在乎(实际上它不会,因为它是模拟的)。这应该是{{1}}方法测试的责任,但由于我假设这实际上是一个EF方法,所以不应该为第三方组件编写测试。