How to Layout Entity Framework 6 with Moq & Autofixture

I use AutoMoq , but I'm a bit confused how to write my first unit test due to Entity Framework (using EF6 and code first) 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>(); 

When I run unit test, it resets

  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, it seems that they make DbSet more prototype.

https://entityframework.codeplex.com/wikipage?title=Design%20Meeting%20Notes%20-%20May%2016%2c%202013

Make DbSet more mock

  • This means adding a secure constructor and creating virtual
  • Note that a type derived from DbSet that uses a protected constructor will create an object that is not bound to any context, and the methods will not work. This makes it very similar to IDbSet in terms of creating test twins.
  • If we took advantage of this option, we could have deprecated IDbSet
  • It is worth noting that not a single case has been identified when this will be functionally different from using IDbSet for double tests. However, there is a strong sense in the community that interfaces are preferable.

Does anyone know how to mock this?

Edit 2

I found this article but it continues to crash

 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)); } 

with the following 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 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 the assembly 'DynamicProxyGenAssembly2, Version = 0.0.0.0, Culture = neutral, PublicKeyToken = a621a9e7e5c32e69, the parameter was no longer limited by parameters.

+6
source share
2 answers

You need to provide a specification that indicates that the DbSet<T> class should be mocked (although this is not an abstract type or interface).

The reason for this is that the DbSet<T> class is public, but has a protected constructor.

Specification

 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(); } } 

An example :

 [Fact] public void Test() { var fixture = new Fixture(); fixture.ResidueCollectors.Add( new MockRelay( new DbSetTypeSpecification())); Assert.DoesNotThrow(() => fixture.Create<PriceService>()); } 

AutoFixture can now provide automatically generated PriceService values.


Note that the MyContext class MyContext also public, and AFAICT also has an open constructor. This means that AutoFixture by default will not provide an instance of the MyContext class with auto-mocking.

(If you can provide your script, I may be able to help further.)

+4
source

There is a NuGet package called AutoFixture.AutoEF that can solve your problem

 fixture.Customize(new EntityCustomization(new DbContextEntityTypesProvider(typeof(MyContext)))); 
+1
source

Source: https://habr.com/ru/post/955815/


All Articles