Search code examples
c#unit-testingmoqmoq-3

Using count method


I am quiet new to Moq Framework and unitests. my goal is to insert some info to the mock object, and want to be able to count the number of objects inserted with a current value.

I build my mock the in the following way:

var mockCpmSqlDbContext = new Mock<CpmSqlDbContext>();
var mockSetPolicies = new Mock<DbSet<Policies>>();

var dataStore = new List<Policies>
{
    new Policies
    {
        PolicyID = 1,
        PolicyName = "policy1",
        PolicyDesc = "policy1desc"
    },
    new Policies
    {
        PolicyID = 2,
        PolicyName = "policy2",
        PolicyDesc = "policy2desc"
    },
};
var policyData = dataStore.AsQueryable();

mockSetPolicies.As<IQueryable<Policies>>().
    Setup(m => m.Provider).Returns(policyData.Provider);
mockSetPolicies.As<IQueryable<Policies>>().
    Setup(m => m.Expression).Returns(policyData.Expression);
mockSetPolicies.As<IQueryable<Policies>>().
    Setup(m => m.ElementType).Returns(policyData.ElementType);
mockSetPolicies.As<IQueryable<Policies>>().
    Setup(m => m.GetEnumerator()).Returns(policyData.GetEnumerator());


mockSetPolicies.Setup(x => x.Create<Policies>()).Returns(() => new Policies());
mockSetPolicies.Setup(x => x.Add(It.IsAny<Policies>())).Callback<Policies>(dataStore.Add);
mockSetPolicies.As<IQueryable<Policies>>().Setup(m => m.GetEnumerator()).Returns(() => policyData.GetEnumerator());

mockSetPolicies.Setup(x => x.Find(It.IsAny<Policies>()));

mockCpmSqlDbContext.Setup(m => m.Policies).Returns(mockSetPolicies.Object);
var service = new MSsqlProvider(mockCpmSqlDbContext.Object);

I have currently two policies in my mock context. I would like to add two more policies with the same name "policy2", so after the adding I would have three object with policy name "policy2".

service.AddPolicy(new Policies {PolicyID = 3, PolicyName = "policy2", PolicyDesc = "pDesc3"});
service.AddPolicy(new Policies { PolicyID = 4, PolicyName = "policy2", PolicyDesc = "pDesc3" });

my add policy function:

public void AddPolicy(Policies policy)
{
    _dbEntities.Policies.Add(policy);
    _dbEntities.SaveChanges();
}

the code that checks the assertion:

//Assert
var expected = 3;
//first, can I know how many object I have the policy name "policy2".
var actual = mockSetPolicies.Object.Count(p => p.PolicyName == "policy2");
//second, can I assert the number of objects I have currently with the name "policy2".
Assert.AreEqual(expected, actual);

this code is now working currectly


Solution

  • have an object to hold the data

    var dataStore = new List<Policies>
    {
        new Policies
        {
            PolicyID = 1,
            PolicyName = "policy1",
            PolicyDesc = "policy1desc"
        },
        new Policies
        {
            PolicyID = 2,
            PolicyName = "policy2",
            PolicyDesc = "policy2desc"
        },
    };
    
    var policyData = dataStore.AsQueryable();
    

    setup the mock to insert the record into your data store.

    mockSetPolicies
        .Setup(x => x.Add(It.IsAny<Policies>()))
        .Callback<Policies>(dataStore.Add);
    

    That is all you were missing.

    From there you should be able to use linq queries like Count() and it will enumerate the mock dbset.

    There are also some minor modifications you need to make to allow the dbset to be enumerated effectively.

    //Change this to use a Func delegate to allow multiple calls.
    mockSetPolicies.As<IQueryable<Policies>>()
        .Setup(m => m.GetEnumerator())
        .Returns(() => policyData.GetEnumerator());
    
    //Set this up to return a new model if it is being used.
    mockSetPolicies
        .Setup(x => x.Create<Policies>())
        .Returns(() => new Policies());
    

    Assuming the service exposes a property that allows access to the dbset you can assert the count there or via the mock it self.

    //Act
    service.AddPolicy(new Policies {PolicyID = 3, PolicyName = "policy2", PolicyDesc = "pDesc3"});
    service.AddPolicy(new Policies { PolicyID = 4, PolicyName = "policy2", PolicyDesc = "pDesc3" });
    ///Assert
    var expected = 3;
    //first, can I know how many object I have the policy name "policy2".
    var actual = mockSetPolicies.Object.Count(p => p.PolicyName == "policy2");
    //second, can I assert the number of objects I have currently with the name "policy2".
    Assert.AreEqual(expected, actual);