2012-08-03 18 views
10

Nunca antes había hecho pruebas unitarias antes, y tropecé y tropecé en mi primera prueba. El problema es que _repository.Golfers.Count(); siempre indica que el DbSet está vacío.Pruebas unitarias Entity Framework con Mock IDbSet

Mi prueba es simple, sólo estoy tratando de agregar un nuevo jugador de golf

[TestClass] 
public class GolferUnitTest //: GolferTestBase 
{ 
    public MockGolfEntities _repository; 

    [TestMethod] 
    public void ShouldAddNewGolferToRepository() 
    { 
     _repository = new MockGolfEntities(); 

     _repository.Golfers = new InMemoryDbSet<Golfer>(CreateFakeGolfers()); 

     int count = _repository.Golfers.Count(); 
     _repository.Golfers.Add(_newGolfer); 

     Assert.IsTrue(_repository.Golfers.Count() == count + 1); 
    } 

    private Golfer _newGolfer = new Golfer() 
    { 
     Index = 8, 
     Guid = System.Guid.NewGuid(), 
     FirstName = "Jonas", 
     LastName = "Persson" 
    }; 
    public static IEnumerable<Golfer> CreateFakeGolfers() 
    { 
     yield return new Golfer() 
     { 
      Index = 1, 
      FirstName = "Bill", 
      LastName = "Clinton", 
      Guid = System.Guid.NewGuid() 
     }; 
     yield return new Golfer() 
     { 
      Index = 2, 
      FirstName = "Lee", 
      LastName = "Westwood", 
      Guid = System.Guid.NewGuid() 
     }; 
     yield return new Golfer() 
     { 
      Index = 3, 
      FirstName = "Justin", 
      LastName = "Rose", 
      Guid = System.Guid.NewGuid() 
     }; 
    } 

he construido un modelo de datos usando Entity Framework y código primero. Me he burlado de una clase derivada de IDbSet con el fin de probar mi contexto (reverencia a la gente en línea que no puedo recordar exactamente)

public class InMemoryDbSet<T> : IDbSet<T> where T : class 
{ 
    readonly HashSet<T> _set; 
    readonly IQueryable<T> _queryableSet; 

    public InMemoryDbSet() : this(Enumerable.Empty<T>()) { } 

    public InMemoryDbSet(IEnumerable<T> entities) 
    { 
     _set = new HashSet<T>(); 

     foreach (var entity in entities) 
     { 
      _set.Add(entity); 
     } 

     _queryableSet = _set.AsQueryable(); 
    } 

    public T Add(T entity) 
    { 
     _set.Add(entity); 
     return entity; 

    } 

    public int Count(T entity) 
    { 
     return _set.Count(); 
    } 

    // bunch of other methods that I don't want to burden you with 
} 

Cuando elimino errores y el paso a través del código que puedo ver que una instancia de la _repository y llenarlo con tres golfistas falsos, pero cuando salgo de la función de agregar, el _respoistory.Golfers está vacío de nuevo. cuando agrego un nuevo golfista, se ejecuta _set.Add(entity) y se agrega el golfista, pero nuevamente _respoistory.Golfers está vacío. ¿Que me estoy perdiendo aqui?

actualización

Lo siento por ser tan idiota, pero no había implementado el set en mi contexto MockGolfEntities. La razón por la que no lo hice es porque lo intenté antes, pero no pude entender cómo, seguí y me olvidé de ello. Entonces, ¿cómo configuro un IDbSet? Esto es lo que he intentado, pero me da un error de desbordamiento de pila. Me siento como un idiota, pero no puedo entender cómo escribir la función de conjunto.

public class MockGolfEntities : DbContext, IContext 
{ 
    public MockGolfEntities() {} 

    public IDbSet<Golfer> Golfers { 
     get { 
      return new InMemoryDbSet<Golfer>(); 
     } 
     set { 
      this.Golfers = this.Set<Golfer>(); 
     } 
    } 
} 
+0

El método 'set' se llama a sí mismo asignando' this.Golfers'. Deberías guardar el valor en alguna parte. Por ejemplo: 'this.golfers = value;' donde 'golfers' es un campo privado (' private IDbSet golfers; '). – Sam

Respuesta

5

No debería ser necesario para implementar el get/set, el siguiente código debería ser suficiente para generar el contexto para usted.

public class MockGolfEntities : DbContext, IContext 
{ 
    public MockGolfEntities() {} 

    public IDbSet<Golfer> Golfers { get; set;} 

} 

He implementado algunas el código que tenía en su puesto original y todo parecía funcionar bien para mí - ¿de dónde sacaste la fuente para la InMemoryDbSet? Estoy usando el NuGet package 1.3, ¿tal vez deberías probar esa versión?

+0

Gracias- Todavía estoy desconcertado sobre cómo implementar el conjunto si quisiera, pero estoy feliz de dejar la magia hasta el IDbSet. Me di cuenta de que mi set era una locura, ya que estoy tratando de establecer la propiedad en un ciclo infinito, pero estaba desesperado y quería publicar un código para mostrar que al menos le di una oportunidad :-). No usé NuGet, pero estoy tratando de usarlo. Gracias por el enlace. –