28 votes

Entity Framework 4.3 et Moq ne peuvent pas créer de DbContext mock

Le test suivant qui fonctionnait avec EF 4.2 lève l'exception suivante avec EF 4.3

System.ArgumentException : Le type à simuler doit être une interface ou une classe abstraite ou non scellée. classe abstraite ou non scellée. ----> System.TypeLoadException : Méthode 'CallValidateEntity' sur le type 'Castle.Proxies.DbContext43Proxy'. à partir de l'assemblage 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' remplace une méthode qui n'est pas qui n'est pas visible dans cet assemblage.

[Test]
public void CanCreateMoqTest()
{
    // Arrange
    Mock<DbContext43> mock;

    // Act
    mock = new Mock<DbContext43>();

    // Assert
    Assert.NotNull(mock.Object);
}

public class DbContext43:DbContext
{
}

Que dois-je faire ? Créer une interface pour mon DbContext43 ?

S'agit-il d'un changement de rupture entre 4.2 et 4.3 ?

Merci !

38voto

Arthur Vickers Points 4894

Merci d'avoir trouvé ça. Le problème est causé par les attributs InternalsVisibleTo que nous avons supprimés de la version EF 4.2 mais laissés dans la version EF 4.3. Cela permettait à Moq (que nous utilisons pour nos tests) de voir les internes de EntityFramework.dll. Cependant, comme votre assembly ne peut pas voir ces éléments internes, vous vous retrouvez avec l'exception.

Nous prévoyons d'effectuer une mise à jour de EF 4.3 dans les prochaines semaines et nous supprimerons InternalsVisibleTo de cette version, après quoi le mocking devrait fonctionner à nouveau.

Mise à jour : Ce problème est maintenant corrigé dans EF 4.3.1 (et EF 5.0-beta1) publié aujourd'hui. Mettez à jour votre paquet NuGet pour obtenir la correction. Voir http://blogs.msdn.com/b/adonet/archive/2012/02/29/ef4-3-1-and-ef5-beta-1-available-on-nuget.aspx pour les détails.

5voto

jimmy_keen Points 14831

Ce type d'exception indique généralement que le membre que vous tentez de remplacer n'est pas exposé en tant que partie de l'interface publique dans l'assemblage donné (ou peut-être pour être plus précis - l'assemblage de remplacement ne le voit pas ). Et si nous Jetez un coup d'œil en CallValidateEntity dans EntityFramework 4.3 :

internal virtual DbEntityValidationResult CallValidateEntity(
    DbEntityEntry entityEntry, IDictionary<object, object> items)
{
    return this.ValidateEntity(entityEntry, items);
}

Nous constatons en effet que cette méthode est internal et, par conséquent, entre dans la catégorie des produits non modifiables ( non modifiable considérant que non InternalsVisibleTo est utilisé). Cela s'accompagne naturellement d'une saisie correcte des métadonnées :

Method #20 (06000a03)
-------------------------------------------------------
  MethodName: CallValidateEntity (06000A03)
  Flags     : [Assem] [Virtual] [HideBySig] [NewSlot]  (000003c3)

La raison pour laquelle Moq tente de remplacer ce membre n'est pas claire... étant donné qu'il ne devrait pas le voir en premier lieu.

Envelopper votre contexte dans une interface et n'exposer que les méthodes que vous utilisez réellement est une option viable - cela devrait être suffisant pour que votre test passe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X