Passing value in Mock Rhino test - c#

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");

Related

Mocking ReturnsAsync using Moq to return 2 values

Given a interface:
Task<Booking> GetBookingAsync(Guid reservationId);
I would mock the following like so:
_bookingLogic.Setup(x => x.GetBookingAsync(It.IsAny<Guid>())).ReturnsAsync(new Booking());
Givent the interface now changes to:
Task<(Booking Booking, IList<GAEvent> GaEvents)> GetBookingAsync(Guid reservationId);
How would this be mocked using Moq?
_bookingLogic.Setup(x => x.GetBookingAsync(It.IsAny<Guid>())).ReturnsAsync(?????);
In second case result is a value tuple so you need to create one. Try:
.ReturnsAsync((new Booking(), (IList<GAEvent>)new List<GAEvent>()))

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.

Understanding Moq's Setup() function

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?

Using Moq to set indexers in C#

I'm having trouble figuring out how to set indexers in C# with Moq. The Moq documentation is weak, and I've done a lot of searching... what I'd like to do is similar in the solution to How to Moq Setting an Indexed property:
var someClass = new Mock<ISomeClass>();
someClass.SetupSet(o => o.SomeIndexedProperty[3] = 25);
I want to modify the above to work for any index and any value so I can just do something like this:
someClass.Object.SomeIndexedProperty[1] = 5;
Currently I have the following, which works great for the indexed property getter, but if I ever set the value Moq ignores it:
var someValues = new int[] { 10, 20, 30, 40 };
var someClass = new Mock<ISomeClass>();
someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()])
.Returns<int>(index => someValues[index]);
// Moq doesn't set the value below, so the Assert fails!
someClass.Object.SomeIndexedProperty[3] = 25;
Assert.AreEqual(25, someClass.Object.SomeIndexedProperty[3]);
I found a solution to my problem. It requires a shift in my thinking... I had been looking to use NUnit's Assert to verify that the indexer setter in my someClass mock was being called with the correct value.
It seems that with Moq the supported way to do this is to use the VerifySet function. A contrived example:
someClass.Object.SomeIndexedProperty[3] = 25;
someClass.VerifySet(mock => mock.SomeIndexedProperty[3] = 25);
The unit test passes since SomeIndexedProperty[3] is set to 25, but would fail otherwise.
Using Moq 3.1.416.3
Setup won't work for indexers (because it takes an expression which means assignment statements are ruled out)
so you need to use SetupSet like
_settingsStore.SetupSet(store => store["MruNotes"] = It.IsAny<string>())
.Callback<string,string>( (key, value) => persistedValue = value);
A small caveat:
this expression only matches if the key is "MruNotes". I was not able to use a matcher like It.IsAny for the key.
In your test your only set expectations for the getter of the indexer - and this will always return the corresponding value from your array. The indexer doesn't behave like a real thing. You can try a few things to have it fixed:
You can check if you can stub this indexer. I am personally using RhinoMocks, so I have no idea if this is implemented
someClass.SetupProperty(f => f.SomeIndexedProperty);
You can try to mock the setter as well and make it to change the underlying array. My first guess would be to try something along these lines (no guarantee it will work):
someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()] = It.IsAny<int>())
.Callback((index, value) => someValues[index] = value);
Or if the ISomeClass interface is small enough, you could just created a stub implementation yourself (that would have the indexer implemented as a dictionary, array etc.)

Finding all classes containing a method in C#

I want to search through all classes in a namespace for those containing a certain method. If a class contains a method then I want to create an instance of the class and run the method.
Obviously I have to start with reflection but I'm stuck on where to go.
Edit:
Interfaces are not the way I want to do this.
What I'm looking for is embedding testing functions into the code but a single calling interface. If there's a self-test function, call it. If there isn't, ignore it.
Create an interface that declares the method and then have various classes implement that interface.
You can then use reflection to find all types within an assembly that implement that interface.
From there you'll need to create an instance of each type and then call the method. The implementation details will vary depending on what you are trying to do.
Update based on comments:
I still think an interface (or attribute) is the way to go. This is how it would work with an interface.
interface ISelfTester
{
void SelfTest();
}
class SomeClass : ISelfTester
{
/* ... */
public void SelfTest()
{
// test code
}
/* ... */
}
You could then invoke each type's SelfTest method like so (borrowing from Dathan and Darren Kopp):
var type = typeof(ISelfTester);
var types = AppDomain.CurrentDomain.GetAssemblies()
.Select(x => x.GetTypes())
.SelectMany(x => x)
.Where(x => x.Namespace == "My.Name.Space" && type.IsAssignableFrom(x));
foreach (Type t in types)
{
ISelfTester obj = Activator.CreateInstance(t) as ISelfTester;
obj.SelfTest();
}
Without more information about what distinguishes the method, I'm just going to assume it's distinguished by name, and it's public. The name assumption is dangerous, so I wouldn't recommend doing this, but the following should do what you want (assuming Activator is able to create an instance).
EDIT: Added Where(x => x.Namespace == "My.Name.Space") to limit the results to a single target namespace.
EDIT: Added if ... else to handle the case of static methods.
var methods = AppDomain.CurrentDomain.GetAssemblies()
.Select(x => x.GetTypes())
.SelectMany(x => x)
.Where(x => x.Namespace == "My.Name.Space")
.Where(c => c.GetMethod("MethodName") != null)
.Select(c => c.GetMethod("MethodName"));
foreach (MethodInfo mi in methods)
{
if (mi.IsStatic)
{
mi.Invoke(null, null); // replace null with the appropriate arguments
}
else if (!mi.DeclaringType.IsAbstract)
{
var obj = Activator.CreateInstance(mi.DeclaringType);
mi.Invoke(obj, null); // replace null with the appropriate arguments
}
}
If you have control over the types, though, jrummel's suggestion about interfaces is a much safer way to do this.
One option would be to use Reflection, as described above, but rather than finding the method by name, look for a method tagged with an appropriate custom attribute. This is similar to what the MS DataContractSerializer does with attributes like [OnDeserializing]. This way the class implementer is specifically spelling out their intent for the method, rather than having it suddenly do something unexpected as a result of it having a particular name.
On a side note, since what you're after is a test method, you might check out something like NUnit. There are several excellent free unit testing frameworks out there. They also provide additional features that can help with your testing, as they provide the scaffolding for the different types of test assertions you might want to make.

Categories

Resources