In one of the tests I was writing using Moq, I needed to test that my repository was called with a particular expression. After struggling for a bit, I found a solution which I am sharing here in hopes that it will benefit you.
1 [Test]
2 public void Then_Repository_Should_Be_Queried_For_Files_In_Pending_Status()
3 {
4 List<JSOFile> dummyFiles = new List<JSOFile>()
5 {
6 new JSOFile() { STATUS_CD = "P", FILE_NM = "teststring"},
7 new JSOFile() { STATUS_CD = "Z", FILE_NM = "test.txt"}
8 };
9
10 _repository.Expect(x => x.FindAll(It.IsAny<Func<JSOFile, bool>>()))
11 .Callback((Func<JSOFile, bool> del) =>
12 {
13 dummyFiles = dummyFiles.Where(del).ToList();
14 });
15
16 _fileManagement = new FileManagement(_repository.Object, _logger.Object, _file.Object, _jsoFileReader.Object, _jsoFileParser.Object);
17
18 _fileManagement.ProcessReceivedFilesToPending();
19
20 Assert.That(dummyFiles.Count == 1, "Expression passed into the FindAll method was incorrect.");
21 Assert.That(dummyFiles.FirstOrDefault().FILE_NM == "teststring");
22
23 _repository.Verify();
24 }
What am I testing?
In the method under test (Line 18 _fileManagement.ProcessReceivedFilesToPending()), I want to ensure that my repository is being queried for the appropriate objects. In this case, all "JSOFile" objects with the STATUS_CD of "P".
The meat of this test method is line 10. This line sets up an expectation that the FindAll(Func<JSOFile, bool>) method will be called from the repository object passed in via constructor (line 16, first parameter).
(_repository defined as:)
_repository = new Moq.Mock<IRepository>();
The Expect method takes a lamba expression that allows you to set an expectation on the type being mocked. In addition to setting expectations, you can also define callbacks. In this example, the callback gets fired when the class under test (_fileManagement) executes the mocked object's FindAll() method. Line 13 will receive the delegate that was passed to the _repository.FindAll. To make sure the delegate was what I expected, I execute the delegate against a list of dummy objects. On lines 20 and 21 I make sure that my list was narrowed down to the object with a status of "P".
Why go to this trouble?
In the future if my repository call gets changed, this test will fail and alert the developer that they've broken intended functionality.