2013-10-11 1 views
6

J'utilise AutoMoq mais je suis un peu confus comment écrire mon premier test de l'unité en raison de son Entity Framework (en utilisant EF6 et premier code) dbContextComment mockup Entity Framework 6 Avec Moq & Autofixture

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

Quand je exécuter le test unitaire, il se bloque

 
    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 

Modifier

Dans EF 6 semble comme ils font le plus DbSet mockable.

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

Faire DbSet plus mockable

  • Ces moyens d'addition d'un constructeur protégé et faire des méthodes virtuelles
  • Notez que un type dérivé de DbSet qui utilise le constructeur protégé créerait un objet ne pas être lié à un contexte et les méthodes seraient no-ops. Cela le rend très similaire à IDbSet du point de vue de la création de doubles de test.
  • Si nous prenons cette option, nous pourrions potentiellement obsolètes IDbSet
  • Il est à noter qu'aucun cas n'a été identifié où cela serait fonctionnellement différent de l'utilisation de IDbSet pour les tests doubles. Cependant, il y a un fort sentiment dans la communauté que les interfaces sont préférées.

Quelqu'un sait comment moquer jusqu'à?

Edit 2

J'ai trouvé this article mais il se bloque

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

à l'exception suivante:

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 » de l'assemblage 'DynamicProxyGenAssembly2, Version = 0.0.0.0, Culture = neutre, PublicKeyToken = a621a9e7e5c32e69' essayé de remplace implicitement une méthode avec des contraintes de paramètres de type plus faibles ».

+1

liés: http: // stackoverflow. com/questions/16696777/test-avec-un-faux-dbcontext-et-autofixture-et-moq et http://stackoverflow.com/questions/14391146/using-autofixture-in-my-data-integration-tests- to-create-proxies et https://autofixture.codeplex.com/discussions/262557 Question: Avez-vous isolé que EF6 se comporte différemment à 5 ou essayez-vous simplement d'être complet? –

+0

Le dernier exemple que vous avez fourni, celui sans AutoFixture fonctionne sur ma machine. J'ai copié vos classes PriceService, MyContext et Test_Price_Object_Setup_Properly. J'ai mis en place ma propre classe de prix car vous ne l'avez pas fournie et elle fonctionne sans aucune exception. J'utilise Entity Framework 6.0 RC 1 et Visual Studio 2013 RC. –

+0

@RubenBartelink Eh bien, ma question a commencé sur la façon de simuler le Datacontext, puis j'ai trouvé que EF pouvait se moquer du dbset et n'avait pas besoin d'un wrapper. J'ai rencontré d'énormes problèmes pendant le tutoriel. Je sais maintenant c'est l'autofixture qui a été le problème, Il installe la version 3.0 de moq mais 4.0 est nécessaire pour que le tutoriel fonctionne. Je ne suis pas sûr s'il est possible d'utiliser l'autofixage maintenant à cause de cela. – chobo2

Répondre

4

Vous devez fournir un specification qui indique que la classe DbSet<T> doit être moqué (bien que ce n'est pas un type abstrait ou interface).

La raison en est que la classe DbSet<T> est publique mais qu'elle a un constructeur protégé.

Spécification:

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

Exemple:

[Fact] 
public void Test() 
{ 
    var fixture = new Fixture(); 
    fixture.ResidueCollectors.Add(
     new MockRelay(
      new DbSetTypeSpecification())); 

    Assert.DoesNotThrow(() => 
     fixture.Create<PriceService>()); 
} 

maintenant AutoFixture peut fournir des valeurs générées automatiquement PriceService.


S'il vous plaît noter que la classe MyContext est aussi public et, AFAICT, il a aussi un constructeur public. Cela signifie que AutoFixture ne fournira pas une instance auto-simulée pour la classe MyContext par défaut.

(. Si vous pouvez fournir votre scénario que je pourrais être en mesure d'aider davantage)

+0

Avez-vous essayé cela contre EF 6? J'ai découvert que la raison pour laquelle rien ne fonctionnait pour moi était AutoFixture installé moq 3 et j'avais besoin de moq 4 pour le tutoriel pour travailler.J'ai essayé de garder moq 4 et autofixture mais je – chobo2

+0

Eh bien, je ne fais que commencer à utiliser l'Autofixture et je ne veux pas créer tous les simulacres (avec moq) et les données factices à la main. C'est ce que j'essaie de faire.Je suis aussi un peu flou quand j'ai besoin de certaines données dans mon simulacre pour être une certaine valeur (disons que le prix dans le PriceObject doit être de 5) – chobo2

+0

@ chobo2 A propos de Moq veuillez lire ma réponse [ ici] (https://autofixture.codeplex.com/workitem/4260). –

1

Il existe un paquet NuGet appelé AutoFixture.AutoEF qui peut résoudre votre problème

fixture.Customize(new EntityCustomization(new DbContextEntityTypesProvider(typeof(MyContext)))); 
Questions connexes