我希望这有帮助:
[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()
方法测试的责任,但由于我假设这实际上是一个 EF 方法,因此您不应该为第三方组件编写测试。