Question

SO follow this example

example and how make a fake DBContex For test my test using just this work fine

[Test]
public void CiudadIndex()
{
    var ciudades = new FakeDbSet<Ciudad>
    {
        new Ciudad {CiudadId = 1, EmpresaId =1, Descripcion ="Santa Cruz", FechaProceso = DateTime.Now, MarcaBaja = null, UsuarioId = 1},
        new Ciudad {CiudadId = 2, EmpresaId =1, Descripcion ="La Paz", FechaProceso = DateTime.Now, MarcaBaja = null, UsuarioId = 1},
        new Ciudad {CiudadId = 3, EmpresaId =1, Descripcion ="Cochabamba", FechaProceso = DateTime.Now, MarcaBaja = null, UsuarioId = 1}
    };

    //// Create mock unit of work
    var mockData = new Mock<IContext>();
    mockData.Setup(m => m.Ciudades).Returns(ciudades);

    // Setup controller
    var homeController = new CiudadController(mockData.Object);

    // Invoke
    var viewResult = homeController.Index();
    var ciudades_de_la_vista = (IEnumerable<Ciudad>)viewResult.Model;

    // Assert..
}

Iam tryign now to use Autofixture-Moq

to create "ciudades" but I cant. I try this

var fixture = new Fixture();
var ciudades = fixture.Build<FakeDbSet<Ciudad>>().CreateMany<FakeDbSet<Ciudad>>();
var mockData = new Mock<IContext>();
mockData.Setup(m => m.Ciudades).Returns(ciudades);

I get this error

Cant convert System.Collections.Generic.IEnumerable(FakeDbSet(Ciudad)) to System.Data.Entity.IDbSet(Ciudad)

cant put "<>" so I replace with "()" in the error message

Implementation of IContext and FakeDbSet

public interface IContext
{
    IDbSet<Ciudad> Ciudades { get; }
}
public class FakeDbSet<T> : IDbSet<T> where T : class

how can make this to work?

Was it helpful?

Solution

A minor point... In stuff like:

var ciudades_fixture = fixture.Build<Ciudad>().CreateMany<Ciudad>();

The second type arg is unnecessary and should be:

var ciudades_fixture = fixture.Build<Ciudad>().CreateMany();

I really understand why you need a FakeDbSet and the article is a bit TL;DR... In general, I try to avoid faking and mucking with ORM bits and instead dealing with interfaces returning POCOs to the max degree possible.

That aside... The reason the normal syntax for initialising the list works is that there is an Add (and IEnumerable) in DBFixture. AutoFixture doesn't have a story for that pattern directly (after all it is compiler syntactic sugar and not particularly amenable to reflection or in line with any other conventions) but you can use AddManyTo as long as there is an ICollection in play. Luckily, within the impl of FakeDbSet as in the article, the following gives us an in:-

public ObservableCollection<T> Local
{
    get { return _data; }
}

As ObservableCollection<T> derives from ICollection<T>, you should be able to:

var ciudades = new FakeDbSet<Cuidad>();
fixture.AddManyTo(ciudades.Local);

var mockData = new Mock<IContext>();
mockData.Setup(m => m.Ciudades).Returns(ciudades);

It's possible to wire up a customization to make this prettier, but at least you have a way to manage it. The other option is to have something implement ICollection (or add a prop with a setter taking IEnumerable<T> and have AF generate the parent object, causing said collection to be filled in.


Long superseded side note: In your initial question, you effectively have:

fixture.Build<FakeDbSet<Ciudad>>().CreateMany()

The problem becomes clearer then - you are asking AF to generate Many FakeDbSet<Ciudad>s, which is not what you want.

OTHER TIPS

I haven't used AutoFixture in a while, but shouldn't it be:

var ciudades = new FakeDbSet<Ciudad>();
fixture.AddManyTo(ciudades);

for the moment I end doing this, I will keep reading about how use automoq, cause I'm new in this

var fixture = new Fixture();
var ciudades_fixture = fixture.Build<Ciudad>().CreateMany<Ciudad>();
var ciudades = new FakeDbSet<Ciudad>();
foreach (var item in ciudades_fixture)
{
    ciudades.Add(item);
}
var mockData = new Mock<IContext>(); 
fixture.Create<Mock<IContext>>();
mockData.Setup(r => r.Ciudades).Returns(ciudades);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top