2

In C#, How do I go about mocking a list of objects?

I am attempting an exercise and it specifies that in the arrange section of my unit test that I need to "mock a List of Book objects".

What is the syntax for creating a mock list of Book objects? I have tried creating mock Book objects and adding them to a list of books but this didn't work.

public void Test_GetAllBooks_ReturnsListOfBooksItReceivesFromReadAllMethodOfReadItemCommand_WhenCalled()
{
    //Arrange
    Mock<ReadItemCommand> mockReadItemCommand = new Mock<ReadItemCommand>();
    Catalogue catalogue = new Catalogue(mockReadItemCommand.Object);

    Mock<Book> mockBook1 = new Mock<Book>();
    Mock<Book> mockBook2 = new Mock<Book>();
    List<Book> mockBookList = new List<Book>();
    mockBookList.Add(mockBook1);
    mockBookList.Add(mockBook2);

    mockReadItemCommand.Setup(r => r.ReadAll()).Returns(mockBookList);

    //Act
    List<Book> actual = catalogue.GetAllBooks();

    //Assert
    Assert.AreSame(mockBookList, actual);

}

This is giving me 2 compilation errors, both CS1503, on the two lines where I have tried to add the mock books to my list of type Book.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Michael Hennigan
  • 375
  • 2
  • 5
  • 15
  • Show what you have tried so far in a [mcve]. maybe then, better help could be provided. Everything in that exercise can be found in this site as it has been asked already. – Nkosi Apr 17 '17 at 16:21
  • 2
    I'm voting to close this question as off-topic because homework questions must show what you've tried so far and be specific about where you're stuck. As written, this is just "gimme teh codez." – EJoshuaS - Stand with Ukraine Apr 17 '17 at 18:12
  • 1
    Okay sorry guys, I'm new to Software Development (hence the question) and new to StackOverflow - no need for that reaction to my question. I thought it was clear that my question was specifically about How Do I Go About Mocking A List Of Objects. Please now see my code above. – Michael Hennigan Apr 19 '17 at 21:09

2 Answers2

5

Just create a list of books to represent fake/mocked data to be returned when exercising the method under test. No need to use Moq for the fake data. Use Moq to mock the dependencies (ReadItemCommand) of the system under test (Catalogue)

public void Test_GetAllBooks_ReturnsListOfBooksItReceivesFromReadAllMethodOfReadItemCommand_WhenCalled()
{
    //Arrange
    var mockReadItemCommand = new Mock<ReadItemCommand>();
    var catalogue = new Catalogue(mockReadItemCommand.Object);

    var expected = new List<Book>(){
        new Book {
            Title = "Book1", 
            //populate other properties  
        },
        new Book { 
            Title = "Book2", 
            //populate other properties  
        }
    };

    mockReadItemCommand
        .Setup(_ => _.ReadAll())
        .Returns(expected);

    //Act
    var actual = catalogue.GetAllBooks();

    //Assert
    Assert.AreSame(expected, actual);
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • Thanks for the solution Nkosi. That's solved the problem of compilation errors. However the exercise specifies both "You will need to mock a List of Book objects" and "You will need to stub the ReadAll() method of your mock ReadItemCommand to return the mock book list". So don't I need a list of mock Books or a mock list of actual Book objects? I was told that only the object being tested should be real and all other objects used in a test should be mocks. [Sorry if these are stupid questions, I'm finding mocking very confusing!] – Michael Hennigan Apr 22 '17 at 15:29
  • @MichaelHennigan the Book list is acting as the mock data source. They are not actual data from the live persisted data. thus they are mocks. the actual mock is the dependency and the list of books are part of that mocked functionality. The only time you would actually mock the Book objects is if the actual object affects the testing of the subject in isolation. – Nkosi Apr 22 '17 at 16:15
  • Okay, thanks for the explanation! I think I finally get it now. – Michael Hennigan Apr 25 '17 at 19:45
0

if i got you right,you can clone the list: for example as shown here:

How do I clone a generic list in C#?

you can clone it in the same way,or instead you can copy the list yourself by creating a new list and add a copy of each element from the source list. hope it helps.

Community
  • 1
  • 1
Coyote
  • 12
  • Hi Coyote. Thanks for the advice. I'm new to C# so bear with me. Is cloning the same as mocking using Moq? Can the same be achieved using mock? I have specifically been asked to use Moq for this exercise. – Michael Hennigan Apr 19 '17 at 21:22