4

I've had a look around at other questions, but nothing really matches what I'm looking for... mainly because I'm not 100% certain on what it is I'm looking for!

Basically I'm working on a new project at the moment, I've created my abstraction layer for DB entities and set the DAC to be repositories. I'm wanting to use unit testing for this with Mock objects, however I've hit a intellectual wall with CRUD (specifically C) operations, my unit test class:

[TestClass]
public class RepositoryTest
{
    private Mock<IPersonRepository> _repository;
    private IList<IPerson> _personStore;

    [TestInitialize()]
    public void Initialize()
    {
        _personStore= new List<IPerson>() {
            new Person() { Name = "Paul" },
            new Person() { Name = "John" },
            new Person() { Name = "Bob" },
            new Person() { Name = "Bill" },
        };

        _repository = new Mock<IPersonRepository>();
        _repository.Setup(r => r.Entirely()).Returns(_personStore.AsQueryable());
    }

    [TestCleanup()]
    public void Cleanup()
    {
        _personStore.Clear();
    }

    [TestMethod()]
    public void Can_Query_Repository()
    {
        IEnumerable<IPerson> people = _repository.Object.Entirely();
        Assert.IsTrue(people.Count() == 4);
        Assert.IsTrue(people.ElementAt(0).Name == "Paul");
        Assert.IsTrue(people.ElementAt(1).Name == "John");
        Assert.IsTrue(people.ElementAt(2).Name == "Bob");
        Assert.IsTrue(people.ElementAt(3).Name == "Bill");
    }

    [TestMethod()]
    public void Can_Add_Person()
    {
        IPerson newPerson = new Person() { Name = "Steve" };

        _repository.Setup(r => r.Create(newPerson));

        // all this Create method does in the repository is InsertOnSubmit(IPerson)
        // then SubmitChanges on the data context
        _repository.Object.Create(newPerson);

        IEnumerable<IPerson> people = _repository.Object.Entirely();
        Assert.IsTrue(people.Count() == 5);
    }
}

My Can_Query_Repository method is successful, however the Can_Add_Person method fails assertion. Now, do I need to do:

  1. Setup the .Create method of the Mock repository to add the element to the _personStore?
  2. Do something else similar?
  3. Abandon all hope as what I want to achieve isn't possible and I'm doing it all wrong!

As always, any help / advice appreciated!

6
  • Just a quick comment to justify why my repository return method is Entirely(). My repository name is AllPeople so I can have AllPeople.WhereAgeIs, AllPeople.WhereDOBIs and AllPeople.Entirely. Commented Sep 29, 2011 at 15:49
  • 1
    You should be testing if you're hitting the Add/Save method in the mock repository interface, not the count. Commented Sep 29, 2011 at 15:55
  • Do you mean the .Verify() method? I've just tried that and the test runs successfully (if I remove the .Count() check)... what does this mean though, does this check the functionality of the method works? Commented Sep 30, 2011 at 8:39
  • 2
    You can test through some sort of integration test that you are really saving the data in the real database. But for unit testing, specially when you mock the repository, all you should test is that you are indeed going to call the save method with right parameters. Otherwise you'll have to create some sort of framework where you add all objects, which kind of defeats the purpose of mocking the repository. Commented Sep 30, 2011 at 13:38
  • Ahhh that makes sense! Yeah it seems I'm trying to test the whole thing in a unit test - which isn't then a unit test! Thanks for that, you should submit that reply as an answer rather than a comment and I'll mark it for you. Cheers! Commented Sep 30, 2011 at 14:17

1 Answer 1

7

Ideally you would do some integration tests for those, but if you want to unit test it, there are possible avenues, including one that wasn't mentioned in the comments of the original question.

The first one. When testing your crud, you can use .Verify to check that the Create methods have really been called.

mock.Verify(foo => foo.Execute("ping"));

With Verify, you can check that the argument was a certain argument, of a certain type and the number of times the method was actually called.

The second one. Or if you want to verify the actual objects that have been added in the repository's collection, what you could do is use the .Callback method on your mock.

In your test create a list that will receive the objects you create. Then on the same line where you call your setup add a callback that will insert the created objects in the list.

In your asserts you can check the elements in the list, including their properties to make sure the correct elements have been added.

var personsThatWereCreated = new List<Person>(); 

_repository.Setup(r => r.Create(newPerson)).Callback((Person p) => personsThatWereCreated.Add(p));

// test code
// ...

// Asserts
Assert.AreEuqal(1, personsThatWereCreated.Count());
Assert.AreEqual("Bob", personsThatWereCreated.First().FirstName);

Granted in your actual example, you create the person and then add it in the setup. Using the callback method here would not be useful.

You could also use this technique to increment a variable to count the number of times it was called.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.