2

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

Dan The Man
  • 1,835
  • 6
  • 30
  • 50
  • Can you provide more information about method `AddPolicy`, please. What is the implementation? Maybe you can verify the calls to `AddPolicy`, but only if the method is _virtual_ . Or you add a new _interface_ to `MSsqlProvider` with `AddPolicy` – Dominik Herold Nov 21 '16 at 13:45
  • @Dominik Herold add policy was added – Dan The Man Nov 21 '16 at 13:54

1 Answers1

2

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);
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • Hi, I get compilation error on the .Callback(policyData .Add); – Dan The Man Nov 21 '16 at 13:58
  • Ok I see where i made the mistake. Hold on let me update it – Nkosi Nov 21 '16 at 14:00
  • sorry again, but the .Callback(dataStore.Add); does not passing compilation – Dan The Man Nov 21 '16 at 14:08
  • Did you separate it like i showed in my example? What is the compilation error message – Nkosi Nov 21 '16 at 14:10
  • actual value is 1, not 3. any ideas why? – Dan The Man Nov 21 '16 at 14:25
  • Update original post with all the new changes made so I can see where the mistake is. Show the full test method as intended. – Nkosi Nov 21 '16 at 14:31
  • Noticed that you did not update the setup for the `GetEnumerator` as suggested in answer. your version returns one enumerator that can only be enumerated once. use the delegate version suggested in answer. And also you are undoing the add and create setup. Remove the second setups `mockSetPolicies.Setup(x => x.Add(It.IsAny())); mockSetPolicies.Setup(x => x.Create());` – Nkosi Nov 21 '16 at 14:40