Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning different mocked values based on parameters passed in Unit Test with Moq

I have a method called GetTasks() that returns 10 tasks objects. I want to moq this task for unit testing purposes. Here is the code:

 _crateRecallService.Setup(m => m.GetTasks(It.IsAny<int>(), It.IsAny<List<Stage>>(), It.IsAny<List<Severity>>())).Returns(new List<CrateRecallTaskWithComms>()
{
    new CrateRecallTaskWithComms() { CrateRecallTas = new CrateRecallTas() { CrateId = "1", PkCTaskID = 1, CampaignId = 1, Severity = "High"}},
    new CrateRecallTaskWithComms() { CrateRecallTas = new CrateRecallTas() { CrateId = "2", PkCTaskID = 2, CampaignId = 2, Severity = "High"}},
    new CrateRecallTaskWithComms() { CrateRecallTas = new CrateRecallTas() { CrateId = "3", PkCTaskID = 3, CampaignId = 3, Severity = "High"}},
    new CrateRecallTaskWithComms() { CrateRecallTas = new CrateRecallTas() { CrateId = "4", PkCTaskID = 4, CampaignId = 4}},
    new CrateRecallTaskWithComms() { CrateRecallTas = new CrateRecallTas() { CrateId = "5", PkCTaskID = 5, CampaignId = 5}},
    new CrateRecallTaskWithComms() { CrateRecallTas = new CrateRecallTas() { CrateId = "6", PkCTaskID = 6, CampaignId = 6}},
    new CrateRecallTaskWithComms() { CrateRecallTas = new CrateRecallTas() { CrateId = "7", PkCTaskID = 7, CampaignId = 7}},
    new CrateRecallTaskWithComms() { CrateRecallTas = new CrateRecallTas() { CrateId = "8", PkCTaskID = 8, CampaignId = 8}},
    new CrateRecallTaskWithComms() { CrateRecallTas = new CrateRecallTas() { CrateId = "9", PkCTaskID = 9, CampaignId = 9}},
    new CrateRecallTaskWithComms() { CrateRecallTas = new CrateRecallTas() { CrateId = "10", PkCTaskID = 10, CampaignId = 10}}

});

This works fine, but there is something missing. Filtering on Task severity would not work here.

My question is, how do I setup Moq so that if the list of Severity passed in has a High Severity within, it will return 3 instead of 10 tasks? So in other words, if I pass it:

// Arrange
var severities = new List<Severity>() { Severity.High };

I want to return 3 tasks instead of 10.

like image 957
J86 Avatar asked Sep 08 '14 08:09

J86


People also ask

What can be mocked with Moq?

Unit testing is a powerful way to ensure that your code works as intended. It's a great way to combat the common “works on my machine” problem. Using Moq, you can mock out dependencies and make sure that you are testing the code in isolation. Moq is a mock object framework for .

Can you mock a class with Moq?

You can use Moq to create mock objects that simulate or mimic a real object. Moq can be used to mock both classes and interfaces. However, there are a few limitations you should be aware of. The classes to be mocked can't be static or sealed, and the method being mocked should be marked as virtual.

Why do we use Moq in unit testing?

Moq is a mocking framework built to facilitate the testing of components with dependencies. As shown earlier, dealing with dependencies could be cumbersome because it requires the creation of test doubles like fakes. Moq makes the creation of fakes redundant by using dynamically generated types.

What is callback in Moq?

A callback is a piece of code that is passed into to a method parameter to be executed from within that method. Callbacks allow you to extend the functionality of such methods. When using Moq to create test doubles, you can supply callback code that is executed when an expectation is met.


1 Answers

Returns not only accepts a value but you can also pass a delegate with an exact signature as your method and actual parameters will be passed to the delegate. Then, you can do whatever you want with these parameters. In your case

 .Returns( (int i, List<Stage> stages, List<Severity> severities) =>
          {
              if ( severities.Contains(...) 
                 return ...
              else
                 ...
          } );
like image 170
Wiktor Zychla Avatar answered Oct 16 '22 18:10

Wiktor Zychla