Search code examples
c#unit-testingmockingmoqstubbing

c# How to mock a list of objects


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.


Solution

  • 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);
    }