Up until now we’ve been using a hand-rolled mock repository to supply data to our app and out unit tests. And while that’s a good first step, it gets clumsy very quickly when trying to cover different scenarios inside out unit tests. For instance, I want to write a test that asserts that the data from the repository is loaded correctly, but I also want to test that my ViewModel behaves correctly if the data retrieval from the repo fails for some reason.
Writing separate classes for each scenario is a tad over the top. fortunately there’s a simple solution: mocking frameworks. Mocking frameworks allow you to mock only the things you need for a test.
sounds a bit fuzzy, I know, so let me just show you how it works. the following code uses the Moq framework – there are others out there if you fancy. Anyway, here’s the code for my previous test, this time using Moq:
OK, let’s take a look at that. First off I’m creating a list of ToDoItems and populate it with a few dummy values. This is the list I want my mock repository to return when its GetAsync() method is called.
After that I create the mock for my IRepository<ToDoItem>. This will essentially have the same function as my MockRepository class before. Except that it’s a lot quicker to create, as you can see.
The following line is where the mocking magic happens. The Setup method of my repo mock takes an argument specifying which method to mock, followed by what that method call should return. Moq supports both synchronous and asynchronous methods now via Returns() and ReturnsAsync() respectively. In this case I’m setting the mock up to return the list of ToDoItems I created earlier whenever the GetAsync() method is called.
Finally I inject the mock for my IRepository<ToDoItem> into the constructor of my OverviewVM class. Note that I’m passing repoMock.Object, not just repoMock as a parameter. This is something that’ll likely catch you out the first few times. It certainly did with me.
After that the code remains the same. I call the LoadData method of my OverviewVM, which promptly returns the list I specified in the setup of my mock. Neat, huh?
…and in the same way we can now test how we want our OverviewVM to react if the repository fails to load the data for some reason. What that reactions should be – now that’s the topic of the next post…