我很难理解我的方法是否正确。我想测试一个存储库。存储库依赖于 DbContext。我希望能够验证存储库没有在作为 DbContext 成员的 IDbSet 类型的属性上调用函数 Add。
我尝试了两种方法。用行为验证,用状态验证。似乎验证行为是正确的,因为谁知道 stub 状态在假对象中做了什么。
public void VerifyBehaviour()
{
// Arrange
var stubEntities = MockRepository.GenerateStub<IWsStatContext>();
var stubManufcturers = MockRepository.GenerateStub<IDbSet<Manufacturer>>();
var manufacturer = new Manufacturer() { Name = "Dummy" };
var manufacturers = new List<Manufacturer>();
manufacturers.Add(manufacturer);
stubManufcturers.Stub(x => x.Local).Return(new System.Collections.ObjectModel.ObservableCollection<Manufacturer>(manufacturers));
stubManufcturers.Stub(x => x.SingleOrDefault(m => m.Name == "Dummy")).Return(manufacturer);
stubEntities.Manufacturers = stubManufcturers;
// Act
var sut = new EquiptmentRepository(stubEntities);
sut.AddManufacturer(manufacturer);
// Assert
stubManufcturers.AssertWasNotCalled(x => x.Add(manufacturer));
}
public void VerifyState()
{
// Arrange
var stubEntities = MockRepository.GenerateStub<IWsStatContext>();
var stubManufacturers = new InMemoryDbSet<Manufacturer>();
var manufacturer = new Manufacturer() { Name = "Dummy" };
stubManufacturers.Add(manufacturer);
stubEntities.Manufacturers = stubManufacturers;
// Act
var sut = new EquiptmentRepository(stubEntities);
sut.AddManufacturer(manufacturer);
// Assert
Assert.AreEqual(stubManufacturers.Count(), 1);
}
验证行为方法因 SingleOrDefault stub 周围的 NullReferenceExceptions 而失败。所以我发现帖子说最好验证状态并使用伪造的 DbSet。但是检查假对象的状态感觉不对。如果 Add 函数的实现方式与真实函数不同(它最初是这样的,即使我的存储库已损坏,我的测试也通过了)怎么办?
有谁知道如何 stub SingleOrDefault 以便我可以检查 Add 是否被调用?我无法检查 Add 是在非 rhinomocked stub 上调用的。
谢谢
最佳答案
如 jimmy_keen's answer 中所述:
SingleOrDefault
is an extension method defined onIEnumerable<T>
(whichIDbSet<T>
implements). Being extension method means it is a static method. RhinoMocks (or any other free tool) cannot mock/stub static methods.
与其尝试“ stub ”扩展方法,不如尝试 stub 扩展方法所基于的底层接口(interface):IEnumerable<T>
stubManufcturers.Stub( x => x.GetEnumerator() ).Return( new List<Manufacturer> { manufacturer }.GetEnumerator() );
通过标记 GetEnumerator()
的行为什么时候SingleOrDefault
被调用时,它将按预期针对虚假枚举执行,并且测试将能够评估行为。
关于c# - 如何使用 Rhino 模拟 stub SingleOrDefault,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10525019/