我正在使用 AutoMoq,但由于 Entity Framework (首先使用 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>();
当我运行单元测试时它崩溃了
at Ploeh.AutoFixture.Kernel.TerminatingSpecimenBuilder.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.AutoPropertiesCommand`1.Execute(Object specimen, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.MethodInvoker.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.c__DisplayClass6.b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Enumerable.d__a5`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.SpecimenFactory.Create[T](ISpecimenContext context, T seed) at Ploeh.AutoFixture.SpecimenFactory.Create[T](ISpecimenContext context) at PriceServiceTests.Test_Price_Object_Setup() in PriceServiceTests.cs:line 26
Edit
In EF 6 seems like they are making the DbSet more mockable.
Make DbSet more mockable
- These means adding a protected constructor and making methods virtual
- Note that a type derived from DbSet that uses the protected constructor would create an object not be bound to any context and the methods would be no-ops. This makes it very like IDbSet from the perspective of creating test doubles.
- If we took this option we could potentially obsolete IDbSet
- It’s worth noting that no cases have been identified where this would be functionally different to using IDbSet for test doubles. However, there is strong feeling in the community that interfaces are preferred.
Anyone know how to mock it up?
Edit 2
I found this article but it keeps crashing
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));
}
有以下异常(exception):
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' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=a621a9e7e5c32e69' tried to implicitly override a method with weaker type parameter constraints`.
最佳答案
您需要提供一个 specification这表示 DbSet<T>
类应该被模拟(尽管它不是抽象类型或接口(interface))。
这是因为 DbSet<T>
类是公共(public)的,但它有一个 protected 构造函数。
规范:
internal class DbSetTypeSpecification : IRequestSpecification
{
public bool IsSatisfiedBy(object request)
{
var type = request as Type;
if (type == null)
return false;
return type.IsGenericType
&& typeof(DbSet<>) == type.GetGenericTypeDefinition();
}
}
示例:
[Fact]
public void Test()
{
var fixture = new Fixture();
fixture.ResidueCollectors.Add(
new MockRelay(
new DbSetTypeSpecification()));
Assert.DoesNotThrow(() =>
fixture.Create<PriceService>());
}
现在 AutoFixture 可以提供自动生成的 PriceService
值(value)观。
请注意 MyContext
类也是公共(public)的,AFAICT,它也有一个公共(public)构造函数。这意味着 AutoFixture 不会为 MyContext
提供自动模拟实例。默认类。
(如果您可以提供您的场景,我也许可以提供进一步的帮助。)
关于c# - 如何使用 Moq 和 Autofixture 模拟 Entity Framework 6,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19328224/