我正在使用AutoMoq,但由于实体框架(首先使用 EF6 和代码),我有点困惑如何编写我的第一个单元测试dbContext
// in service class(constructor)
private readonly MyContext context;
public PriceService(MyContext context)
{
this.context = context;
}
// following would be in nunit test method.
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var priceService = fixture.Create<PriceService>();
当我运行单元测试时它崩溃了
在 Ploeh.AutoFixture.Kernel.TerminatingSpecimenBuilder.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.RecursionGuard.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.RecursionGuard.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.RecursionGuard.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.AutoPropertiesCommand`1.Execute(对象标本,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.RecursionGuard.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.RecursionGuard.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.RecursionGuard.Create(对象请求,ISpecimenContext 上下文) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Collections.Generic.List`1..ctor(IEnumerable`1 集合) 在 System.Linq.Enumerable.ToList[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.MethodInvoker.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.RecursionGuard.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__a5`1.MoveNext() 在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 源) 在 Ploeh.AutoFixture.Kernel.RecursionGuard.Create(对象请求,ISpecimenContext 上下文) 在 Ploeh.AutoFixture.SpecimenFactory.Create[T](ISpecimenContext 上下文,T 种子) 在 Ploeh.AutoFixture.SpecimenFactory.Create[T](ISpecimenContext 上下文) 在 PriceServiceTests.cs:line 26 中的 PriceServiceTests.Test_Price_Object_Setup()
编辑
在 EF 6 中,它们似乎使 DbSet 更加可模拟。
使 DbSet 更可模拟
- 这意味着添加一个受保护的构造函数并使方法成为虚拟的
- 请注意,从使用受保护构造函数的 DbSet 派生的类型将创建一个不绑定到任何上下文的对象,并且方法将是无操作的。从创建测试替身的角度来看,这使得它非常像 IDbSet。
- 如果我们采用这个选项,我们可能会废弃 IDbSet
- 值得注意的是,没有发现这与使用 IDbSet 进行测试替身在功能上有所不同的情况。但是,社区中有一种强烈的感觉,即首选接口。
有谁知道如何模拟它?
编辑 2
我找到了这篇文章,但它总是崩溃
public class MyContext : DbContext
{
//public GroceryListContext()
// : base()
//{
//}
public virtual DbSet<Price> Prices { get; set; }
}
[Test]
public void Test_Price_Object_Setup_Properly()
{
var mockContext = new Mock<MyContext>();
var mockSet = new Mock<DbSet<Price>>(); // had to add EF to my test solution.
mockContext.Setup(m => m.Prices).Returns(mockSet.Object);
var service = new PriceService(mockContext.Object);
// dies when using autofixture so thought try first moq like in article
//var priceService = fixture.Create<PriceService>();
Assert.That(true, Is.EqualTo(false));
}
除了以下例外:
MyContext.Tests.Services.PriceServiceTests.Test_If_Price_Object_Setup_Properly:
System.ArgumentException : Type to mock must be an interface or an abstract or non-sealed class. ----> System.TypeLoadException : Method 'Create' on type 'DbSet
1Proxyb409fc6b430b4568aac048b60ea2f02e 来自程序集 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=a621a9e7e5c32e69' 试图隐式覆盖具有较弱类型参数约束的方法。