Understanding Moq's Setup() function - c#

I have some confusion with Setup().
From my understanding when we declare:
Mock<IUnitOfWork> uwork = new Mock<IUnitOfWork>();
We are creating a mock repository that will never actually reach-out to a database. Since it never touches the database we have to give it some mock data.
For example:
Question question = new Question {
Title = "General question",
Message = "Message body text..."
}
Here's where I'm a bit confused. From my understanding we are telling our Mocked repository what data to return and under which circumstance to return it.
// in this circumstance // return this
uwork.Setup(i =. i.QuestionsRepository.GetById(1)).Returns(question)
At this point we create an instance of our controller and pass uwork.object to the controller instance. When the controller calls the (circumstance) method, our Mock repository produces the return value we specified.
Question
Is this correct? If not stop me here and correct me. If so, then why doesn't something like this work and how do I resolve this?
Controller:
uwork.QuestionRepository.GetAll().Where(l => l.Message_Id == id).ToList();
TestController:
uwork.Setup(i => i.QuestionsRepository
.GetAll().Where(l => l.Message_Id == 1).ToList())
.Returns(questions);
// questions is a List<Question>
I get an exception:
An exception of type 'System.NotSupportedException' occurred in
Moq.dll but was not handled in user code
Additional information: Expression references a method that does not
belong to the mocked object: i =>
i.LegalInquiryRepository.GetAll().Where(l =>
l.legalCommunication_Id ==

You're getting that exception because you're trying to set up a method (Where) that does not belong to the mock (uwork).
You need to first setup the i.QuestionRepository property, then the GetAll method.
The Where method (assuming it's the one defined for IQueryable) cannot be mocked because it's static - but that's ok. Just make sure that the source collection has the correct elements, and Where will select them.
var questionsRepoMock = //...
uwork.SetupGet(i => i.QuestionsRepository).Returns(questionsRepoMock.Object);
questionsRepoMock.Setup(r => r.GetAll())
.Returns(questions);

The Where() and ToList() included in the setup is causing the error. Have you tried without it?
uwork.Setup(i => i.QuestionsRepository.GetAll()).Returns(questions);
What are you trying to do exactly?

Related

How to provide mock values in a FeedResponse for CosmosSDK v3+?

I'm writing a data access layer for my application and trying to mock out the CosmosDB SDK dependency for unit testing. I am using NUnit with NSubstitute and have come across the issue where I am trying to mock the return values for Container.GetItemQueryIterator.
I have successfully provided a mock feedIterator as a response for that call and a mock feedResponse as a return value for feedIterator.ReadNextAsync, but I cannot figure out how to inject any sort of values into the FeedResponse to test against
The code I'm trying to test looks like this:
var feedIterator = container.GetItemQueryIterator<T>(queryDefinition);
while (feedIterator.HasMoreResults){
result.success = true;
foreach (var item in await feedIterator.ReadNextAsync()){
list.Add(item);
}
}
My attempt at mocking out the dependencies like this (Simplified):
this.mockFeedResponse = Substitute.For<FeedResponse<T>>(this.mockApplicationList);
this.mockFeedIterator = Substitute.For<FeedIterator<T>>();
this.mockFeedIterator.ReadNextAsync().ReturnsForAnyArgs(Task.FromResult(this.mockFeedResponse));
this.mockFeedIterator.HasMoreResults.Returns(true);
Looking at the AzureCosmosDB SDK documentation, there seems to be a FeedResponse constructor for mocking that takes an IEnumerable as a parameter, but NSubstitute complains telling me it can't find this constructor when I attempt to pass in a list to use. Is there an alternative that I can feed some IEnumerable as a FeedResponse? Where am I going wrong?
I also managed the issue by mocking the GetEnumerator call on the FeedResponse mock. However, something to keep in mind is that if you just set mockFeedIterator.HasMoreResults(true), you'll end up in an infinite loop.
I solved that problem by using Moq's Callback method feature. I configured the HasMoreResults method to return true, and then setup a callback on the ReadNextAsync method to reconfigure HasMoreResults to return false. That way, it will drop into the while loop the first time, populate the return collection based on the mocked GetEnumerator method, and then exit the loop and return that collection to the test method.
var myItems = new List<MyItem>
{
new MyItem(),
new MyItem()
};
var feedResponseMock = new Mock<FeedResponse<MyItem>>();
feedResponseMock.Setup(x => x.GetEnumerator()).Returns(myItems.GetEnumerator());
var feedIteratorMock = new Mock<FeedIterator<MyItem>>();
feedIteratorMock.Setup(f => f.HasMoreResults).Returns(true);
feedIteratorMock
.Setup(f => f.ReadNextAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(feedResponseMock.Object)
.Callback(() => feedIteratorMock
.Setup(f => f.HasMoreResults)
.Returns(false));
var containerMock = new Mock<Container>();
containerMock
.Setup(c => c.GetItemQueryIterator<MyItem>(
It.IsAny<QueryDefinition>(),
It.IsAny<string>(),
It.IsAny<QueryRequestOptions>()))
.Returns(feedIteratorMock.Object);
You can mock ReadNextAsync to return a mock of FeedResponse that only has GetEnumerator() defined. The GetEnumerator of the List you create will then be passed through to the underlying implementation of the foreach.
The following example uses Moq, but you should be able to do something similar in your implementation.
var mockFeedResponse = new Mock<FeedResponse<Thing>>();
mockFeedResponse
.Setup(x => x.GetEnumerator())
.Returns(
new List<Thing>
{
new Thing(),
new Thing()
}.GetEnumerator()
);
For what it's worth - I worked around this by changing my code to access the Resource field on the FeedResponse received from CosmosDB. In my tests, I was able to then mock the return value for Resource and get the desired result.

How to avoid or UnitTest the accidental use of a concrete singleton type instead of its abstraction with StructureMap

I recently had the following bug in my code which took me for ever to debug. I wanted to inject an instance based on its interface like this:
MovementController(IMotorController motorController)
However I accidentally used the concrete type like this:
MovementController(MotorController motorController)
The project still built and ran fine until I tried to access the motorController from the MovementController instance. Since the underlying implementation of IMotorController accesses hardware, it has to be a singleton or my locks code. However, since I had other classes with the injected IMotorController, I now had two instances MotorController in my object-graph, which both accessed the hardware over a serial connection. This caused an error, at run time at a much lower level, which took me forever to debug and find the true cause.
How can I avoid this type of bug or write a unit test for my StructureMap registry to catch this subtle bug?
You could easily check for this using a static analysis tool like NDepend. With it you would just look for types that were controllers and then inspect their constructors and warn if you found any constructor parameters that were not interface types.
Just to refine the Steve answer, you could write a code rule that could look like: (with NDepend a code rule is a C# LINQ query prefixed with warnif count > 0)
// <Name>Don't use MotorController, use IMotorController instead</Name>
warnif count > 0
from m in Application.Methods
where m.IsUsing ("NamespaceA.MotorController ") &&
m.ParentType.FullName != "NamespaceB.ClassThatCanUseMotorController "
select m
The rule can be refined easily if there are zero or many ClassThatCanUseMotorController.
The safest solution is to check during runtime that only one instance of MotorController is created. For instance you could count the number of instances of MotorController with a static counter variable:
public class MotorController : IMotorController
{
private static bool instantiated;
public MotorController(...)
{
if (instantiated)
throw new InvalidOperationException(
"MotorController can only be instantiated once.")
...
instantiated = true;
}
...
}
I'd usually consider this bad design, because whether a class is used as a singleton or not is something only the dependency injection framework should care about. Also note that this is not thread-safe.
Ok. So the solution I came up with for my Unit Test, is to get all the instances that implement IMotorController and assert that their count equals 1:
var motorControllerInstances = container.GetAllInstances<IMotorController>().Select(x => x); // cast enumerable to List using Linq
Assert.True(motorControllerInstances.Count == 1);
Not sure this is the most elegant way, but it seems to work.
Update 1:
This code does not catch the bug I had. I am still looking for a correct answer to my problem.
Update 2: I am getting closer. This will at least catch if you have accidentally registered a concrete type of the corresponding interface. However, it does not appear to check whether an instance of it was actually built.
var allInterfaceInstances = dicFixture.result.Model.GetAllPossible<IMotorController>();
Assert.True(allInterfaceInstance.Count() == 1);
In trying to adhere to the D in SOLID
Dependency inversion principle where
one should “Depend upon Abstractions. Do not depend upon concretions
for a project. In this case Asp.Net-MVC5, I wanted a way to make sure that all controllers (MVC and WebAPI2) were following this pattern where they were not dependent on concretions.
The original idea came from an article I had read where a unit test was created to scan all controllers to make sure that they had explicit authorization defined. I applied a similar thinking in checking that all controllers had constructors that depended on abstractions.
[TestClass]
public class ControllerDependencyTests : ControllerUnitTests {
[TestMethod]
public void All_Controllers_Should_Depend_Upon_Abstractions() {
var controllers = UnitTestHelper.GetAssemblySources() //note this is custom code to get the assemblies to reflect.
.SelectMany(assembly => assembly.GetTypes())
.Where(t => typeof(IController).IsAssignableFrom(t) || typeof(System.Web.Http.Controllers.IHttpController).IsAssignableFrom(t));
var constructors = controllers
.SelectMany(type => type.GetConstructors())
.Where(constructor => {
var parameters = constructor.GetParameters();
var result = constructor.IsPublic
&& parameters.Length > 0
&& parameters.Any(arg => arg.ParameterType.IsClass && !arg.ParameterType.IsAbstract);
return result;
});
// produce a test failure error mssage if any controllers are uncovered
if (constructors.Any()) {
var errorStrings = constructors
.Select(c => {
var parameters = string.Join(", ", c.GetParameters().Select(p => string.Format("{0} {1}", p.ParameterType.Name, p.Name)));
var ctor = string.Format("{0}({1})", c.DeclaringType.Name, parameters);
return ctor;
}).Distinct();
Assert.Fail(String.Format("\nType depends on concretion instead of its abstraction.\n{0} Found :\n{1}",
errorStrings.Count(),
String.Join(Environment.NewLine, errorStrings)));
}
}
}
So given the following example. (Note I adapted this to MVC)
public class MovementController : Controller {
public MovementController(MotorController motorController) {
//...
}
}
public interface IMotorController {
//...
}
public class MotorController : IMotorController {
//...
}
the unit test would fail with ...
Result Message: Assert.Fail failed.
Type depends on concretion instead of its abstraction.
1 Found :
MovementController(MotorController motorController)
This worked for me because I had a common type to look for with the IController and ApiController.
There is room for improvement on the test but is should be a good starting point for you.

Passing value in Mock Rhino test

I have following code:
if (ActiveApplication.GetField("previous_date").Value != ActiveApplication.GetField("new_date").Value)
{
//do something..
}
I want to unit test this. Being new to Rhino tests, I am trying to figure out how to pass value so that i go in the loop. Here is what i have tried:
var previous_date = MockRepository.GenerateMock<IField>();
stubApplication.Stub(x => x.GetField("previous_date")).Return(previous_date);
previous_date.Stub(x => x.GetInternalValue()).Return("20160525");
var new_date = MockRepository.GenerateMock<IField>();
stubApplication.Stub(x => x.GetField("new_date")).Return(new_date);
new_date.Stub(x => x.GetInternalValue()).Return("20160525");
Can someone please tell me what am i doing wrong?
This returns previous_date, an interface of type IField:
stubApplication.Stub(x => x.GetField("previous_date")).Return(previous_date)
Because it's not a base class implementation, your code uses the Value property on the interface which has to be setup in a mock as well, rather than using GetInternalValue(). Same with new_stub.
EDIT: You need essentially to do the following (note I'm not sure if this is the correct syntax as I haven't used that framework, but I'm trying to capture the essence):
previous_date.Stub(x => x.Value).Return("20160525");

SetupSequence in Moq

I want a mock that returns 0 the first time, then returns 1 anytime the method is called thereafter. The problem is that if the method is called 4 times, I have to write:
mock.SetupSequence(x => x.GetNumber())
.Returns(0)
.Returns(1)
.Returns(1)
.Returns(1);
Otherwise, the method returns null.
Is there any way to write that, after the initial call, the method returns 1?
The cleanest way is to create a Queue and pass .Dequeue method to Returns
.Returns(new Queue<int>(new[] { 0, 1, 1, 1 }).Dequeue);
That's not particulary fancy, but I think it would work:
var firstTime = true;
mock.Setup(x => x.GetNumber())
.Returns(()=>
{
if(!firstTime)
return 1;
firstTime = false;
return 0;
});
Bit late to the party, but if you want to still use Moq's API, you could call the Setup function in the action on the final Returns call:
var mock = new Mock<IFoo>();
mock.SetupSequence(m => m.GetNumber())
.Returns(4)
.Returns(() =>
{
// Subsequent Setup or SetupSequence calls "overwrite" their predecessors:
// you'll get 1 from here on out.
mock.Setup(m => m.GetNumber()).Returns(1);
return 1;
});
var o = mock.Object;
Assert.Equal(4, o.GetNumber());
Assert.Equal(1, o.GetNumber());
Assert.Equal(1, o.GetNumber());
// etc...
I wanted to demonstrate using StepSequence, but for the OP's specific case, you could simplify and have everything in a Setup method:
mock.Setup(m => m.GetNumber())
.Returns(() =>
{
mock.Setup(m => m.GetNumber()).Returns(1);
return 4;
});
Tested everything here with xunit#2.4.1 and Moq#4.14.1 - passes ✔
You can use a temporary variable to keep track of how many times the method was called.
Example:
public interface ITest
{ Int32 GetNumber(); }
static class Program
{
static void Main()
{
var a = new Mock<ITest>();
var f = 0;
a.Setup(x => x.GetNumber()).Returns(() => f++ == 0 ? 0 : 1);
Debug.Assert(a.Object.GetNumber() == 0);
for (var i = 0; i<100; i++)
Debug.Assert(a.Object.GetNumber() == 1);
}
}
Just setup an extension method like:
public static T Denqueue<T>(this Queue<T> queue)
{
var item = queue.Dequeue();
queue.Enqueue(item);
return item;
}
And then setup the return like:
var queue = new Queue<int>(new []{0, 1, 1, 1});
mock.Setup(m => m.GetNumber).Returns(queue.Denqueue);
Normally, I wouldn't bother submitting a new answer to such an old question, but in recent years ReturnsAsync has become very common, which makes potential answers more complicated.
As other have stated, you can essentially just create a queue of results and in your Returns call pass the queue.Dequeue delegate.
Eg.
var queue = new Queue<int>(new []{0,1,2,3});
mock.SetupSequence(m => m.Bar()).Returns(queue.Dequeue);
However, if you are setting up for an async method, we should normally call ReturnsAsync. queue.Dequeue when passed into ReturnsAsync and will result in the first call to the method being setup working correctly, but subsequent calls to throw a Null Reference Exception. You could as some of the other examples have done create your own extension method which returns a task, however this approach does not work with SetupSequence, and must use Returns instead of ReturnsAsync. Also, having to create an extension method to handle returning the results kind of defeats the purpose of using Moq in the first place. And in any case, any method which has a return type of Task where you have passed a delegate to Returns or ReturnsAsync will always fail on the second call when setting up via SetupSequence.
There are however two amusing alternatives to this approach that require only minimal additional code. The first option is to recognize that the Mock object's Setup and SetupAsync follow the Fluent Api design patterns. What this means, is that technically, Setup, SetupAsync, Returns and ReturnsAsync actually all return a "Builder" object. What I'm referring to as a Builder type object are fluent api style objects like QueryBuilder, StringBuilder, ModelBuilder and IServiceCollection/IServiceProvider. The practical upshot of this is that we can easily do this:
var queue = new List<int>(){0,1,2,3};
var setup = mock.SetupSequence(m => m.BarAsync());
foreach(var item in queue)
{
setup.ReturnsAsync(item);
}
This approach allows us to use both SetupSequence and ReturnsAsync, which in my opinion follows the more intuitive design pattern.
The second approach is to realize that Returns is capable of accepting a delegate which returns a Task, and that Setup will always return the same thing. This means that if we were to either create an an extension method for Queue like this:
public static class EMs
{
public static async Task<T> DequeueAsync<T>(this Queue<T> queue)
{
return queue.Dequeue();
}
}
Then we could simply write:
var queue = new Queue<int>(new []{0,1,2,3});
mock.Setup(m => m.BarAsync()).Returns(queue.DequeueAsync);
Or would could make use of the AsyncQueue class from Microsoft.VisualStudio.Threading, which would allow us to do this:
var queue = new AsyncQueue<int>(new []{0,1,2,3});
mock.Setup(m => m.BarAsync()).Returns(queue.DequeueAsync);
The main problem that causes all of this, as that when the end of a setup sequence has been reached, the method is treated as not being setup. To avoid this, you are expected to also call a standard Setup if results should be returned after the end of the sequence has been reached.
I have put together a fairly comprehensive fiddle regarding this functionality with examples of the errors you may encounter when doing things wrong, as well as examples of several different ways you can do things correctly.
https://dotnetfiddle.net/KbJlxb
Moq uses the builder pattern, setting up the behavior of the mocks.
You can, but don't have to use the fluent interface.
Keeping that in mind, I solved the problem this way:
var sequence = myMock
.SetupSequence(""the method I want to set up"");
foreach (var item in stuffToReturn)
{
sequence = sequence.Returns(item);
}

How can an IRepository be unit tested?

I have written the following method using the Repository mentioned
in the following blog-post (http://www.codecapers.com/post/Using-RavenDB-with-ASPNET-MVC.aspx) using RavenDB:
public User GetUserById(string id)
{
var user = (from usr in _repository.All<User>() where usr.Id == id select usr).FirstOrDefault();
if (user == null)
{
throw new NullReferenceException("No user with the id (" + id + ") could be found.");
}
return user;
}
How would you unit test this method with nunit (and perhaps moq)?
"user" is just a normal class.
Usualy you don't write tests directly against the repository layer.
Say for example you are using nHibernate or Entity Framework, than wirting tests against the repository would technically be testing that framework.
The creators or those ORMs already done that.
Also talking to a database makes your test an integration test not a unit test.
Your unit test would be for example against the business layer mocking out the repository layer.
If you want to write an integration test you also write that against the business layer but don't mock the repository layer and let it go through.
I would do the following to prepare your code:
Make sure your _repository is being passed in through a constructor or property, so that it can be easily changed for tests.
Make sure your _repository variable is declared as the IRepository type, rather than the concrete type.
Then, in your tests:
Create a mock of your interface and pass this in to be your _repository.
Override the .All<User>() method to return a known, hardcoded list of User with suitable values for your tests.
Assert in one test that the correct value is returned when you query an existing ID.
Assert in a separate test that the exception is thrown when you query a non-existant ID.
The first question is going to be - what are you testing in this context? The method provided really only has two outcomes, so you're basically testing whether user is null or not. Is that a value added test?
As for the how, Im assuming _repository is injected via some mechanism? If so, then you simply provide a Mock<IRepository> (insert your type name as appropriate) and inject that in the place of _repository wherever that is injected. Then you can setup the return values and test your method for the exception or not.
mockRepository.Setup(x => x.All<User>()).Returns(new List<User> { ... });
RavenDB is specifically designed so that you don't need to mock everything for unit testing.
Just run it in-memory and you can then perform you unit tests against it directly. See this blog post for more info.
It lets you write code like this:
[Fact]
public void CanQueryForDistinctItemsUsingLinq()
{
using (var store = NewDocumentStore())
{
using (var s = store.OpenSession())
{
s.Store(new { Name = "ayende" });
s.Store(new { Name = "ayende" });
s.Store(new { Name = "rahien" });
s.SaveChanges();
}
store.DocumentDatabase.PutIndex("test", new IndexDefinition
{
Map = "from doc in docs select new { doc.Name }",
Stores = { { "Name", FieldStorage.Yes } }
});
using (var s = store.OpenSession())
{
var objects = s.Query<User>("test")
.Customize(x => x.WaitForNonStaleResults())
.Select(o => new {o.Name })
.Distinct()
.ToList();
Assert.Equal(2, objects.Count);
Assert.Equal("ayende", objects[0].Name);
Assert.Equal("rahien", objects[1].Name);
}
}
}
This comes from RavenDB unit/integration tests, so you'll need some infasctucture to get it working, but it gives the general idea.

Categories

Resources