Mike Witt Mike Witt - 2 months ago 20
C# Question

Moq not resolving ICollection reference

I am using Moq.4.2.1507.0118 and I'm having a problem that I have not seen before. The situation is that I have two classes in my model (A and B) with a one to many relationship. For example:

[Table("A")]
public partial class A
{

public A()
{
this.theB = new HashSet<B>();
}

[Key]
public int AId{ get; set; }
public string Name{ get; set; }

public virtual ICollection<B> theB{ get; set; }

}

[Table("B")]
public partial class B
{
[Key]
public int BId{ get; set; }
public int AId{ get; set; }
public virtual A theA { get; set; }
}


Of course I also have the DbSet's defined in the DbContext.

Then, in my test code, I have:

[TestMethod]
public void SomeTest()
{
var theAs = new List<A>
{
new A{ AId=1, Name="test" }
};
var theBs= new List<B>
{
new B{ BId=1, AId=1, theA=theAs[0] }
};

var ASet= new Mock<DbSet<A>>().SetupData(theAs);
var BSet= new Mock<DbSet<B>>().SetupData(theBs);

var context = new Mock<MyContext>();
context.Setup(s => s.A).Returns(ASet.Object);
context.Setup(s => s.B).Returns(BSet.Object);

var m = new ClassThatImTesting(context);
m.someMethod("test");
}


Normally I would see that this is enough to let A and B know about each other in the mock context. However, in the method that I'm testing, if I run something like this:

var result = context.A.Where(x => x.theB.Count() > 0).FirstOrDefault();


I get null. Since I've done this in so many other tests without a problem, I'm having a hard time seeing what I've done to trip this up. Any ideas would be helpful! I've simplified this example from my actual code, so please forgive syntax errors.

Answer

You need to instantiate the collection to the A object before injecting the context to the class.

    [TestMethod]
    public void SomeTest()
    {
        var theAs = new List<A>
        {
            new A{ AId=1, Name="test" }
        };
        var theBs= new List<B>
        {
            new B{ BId=1, AId=1, theA=theAs[0] }
        };
        //here
        theAs[0].theB = theBs

        var ASet= new Mock<DbSet<A>>().SetupData(theAs);
        var BSet= new Mock<DbSet<B>>().SetupData(theBs);

        var context = new Mock<MyContext>();
        context.Setup(s => s.A).Returns(ASet.Object);
        context.Setup(s => s.B).Returns(BSet.Object);

        var m = new ClassThatImTesting(context);
        m.someMethod("test");
    }
Comments