How do you create an echoing mock using Moq? - c#

I am creating a mock for my ITransformer interface.
public interface ITransformer
{
String Transform( String input );
}
I can create a mock that returns an given string based on a specific input:
var mock = new Mock<ITransformer>();
mock.Setup(s => s.Transform("foo")).Returns("bar");
What I would like to do is create a mock with a Transform() method that echoes whatever is passed to it. How would I go about doing this? Is it even possible?
I realise my question might be subverting the way that Moq and mocks in general are supposed to work because I'm not specifying a fixed expectation.
I also know that I could easily create my own class to do this, but I was hoping to find a generic approach that I could use in similar circumstances without having to define a new class each time.

var mock = new Mock<ITransformer>();
m.Setup(i => i.Transform(It.IsAny<string>())).Returns<string>((string s) => { return s;});

var mock = new Mock<ITransformer>();
mock.Setup(t => t.Transform(It.IsAny<string>())).Returns((String s) => s);
This should echo back whatever was supplied to the method.

Related

Moq Setup override

I have gone through all the previous answers and none of them solve my problem.
lets say that i have the following code:
public interface ISomeInterface
{
int SomeMethod(int a, string b);
}
Now i have a common mocking class that defines some default behaviour for the above method
public class CommonMock
{
public Mock<ISomeInterface> MockInterface = new Mock<ISomeInterface>().Setup(x => x.SomeMethod(It.IsAny<int>(), It.IsAny<string>())).Returns(It.IsAny<int>());
}
I need some default behaviour because I have a whole lot of test cases which need a default behaviour.
But in some specific test scenarios, in a totally separate test class, i need to be able to return a different value as i am testing some specific test case.
Something like below:
[Test]
public void TestSomeMethodSpecific()
{
var commonMock = new CommonMock();
commonMock.MockInterface.Setup(x => x.SomeMethod(It.IsAny<int>(), It.IsAny<string>())).Returns(42);
// Do some test based on the new return value
}
How can I achieve that?
Below i am attaching a bit of the actual code:
Common Setup
public class MockStore
{
public Mock<IProcessHandler> ProcessHandler = new Mock<IProcessHandler>();
ProcessHandler.Setup(x => x.GetCurrentProcessRunId()).Returns(It.IsAny<int>());
}
Overridden Setup in a test class
var mockstore = new MockStore();
mockStore.ProcessHandler.Setup(x => x.GetCurrentProcessRunId()).Returns(25);
And there are almost 50 to 70 such mocks each of which return from simple types to complex classes.
That should work? If you create a subsequent setup on a method and it's non-conditional (no constraints on the arguments) then it removes all previous setups for the method.
You can see my answer here that explains it with the source code.
If you want multiple Setups that are conditional, to return different values based on the arguments, then see How to setup a method twice for different parameters with mock.
Without seeing your full code, perhaps you are already using conditional Setups. In which case the order is important and perhaps you are overriding an earlier Setup with a more general one.
You could have global mock objects that you modify as you go. For instance I have this:
[TestClass]
public class StoreServiceTest
{
Mock<IAccess> mockAccess;
Mock<IAccess> mockAccessNoData;
Mock<IDataReader> mockReader;
Mock<IDataReader> mockReaderNoData;
Mock<IStoreService> mockStoreService;
And then on the TestInitiailize, I Setup the default implementation as follows:
mockReader = new Mock<IDataReader>();
mockReader.Setup(m => m.IsDBNull(It.IsAny<int>())).Returns(false);
mockReader.Setup(m => m.GetString(It.IsAny<int>())).Returns("stub");
mockReader.Setup(m => m.GetBoolean(It.IsAny<int>())).Returns(true);
mockReader.Setup(m => m.GetInt32(It.IsAny<int>())).Returns(32);
mockReader.SetupSequence(m => m.Read()).Returns(true).Returns(false); // setup sequence to avoid infinite loop
mockAccess = new Mock<IAccess>();
mockAccess.Setup(m => m.ReadData(It.IsAny<string>(), It.IsAny<object[]>())).Returns(mockReader.Object);
mockReaderNoData = new Mock<IDataReader>();
mockReaderNoData.Setup(m => m.Read()).Returns(false);
mockAccessNoData = new Mock<IAccess>();
mockAccessNoData.Setup(m => m.ReadData(It.IsAny<string>(), It.IsAny<object[]>())).Returns(mockReaderNoData.Object);
mockStoreService = new Mock<IStoreService>();
And now for a default kind of test, all I do is pass the mockReader.Object which should have the default implementation since every test begins with TestInitialize, and then for a special case, say I want to return "sub" instead of "stub" for IDataReader's GetString() method, I can do something like this:
mockReader.Setup(m => m.GetString(It.IsAny<int>())).Returns((int col) => {
if (col == 2) return "sub";
else return "stub";
});
Hope that helps!

How to Mock with Moq to do foreach row in table

I'm a C# and Moq newb. I have some code that looks like the following and I want to unit test it, using Moq.
Data.Foo.FooDataTable tbl = Adapter.GetFooByID(id);
foreach (Data.Foo.FooRow row in tbl)
{
x = row.bar
...
}
How do I set up the mocks? Current broken attempt:
var adapter = new Mock<FooTableAdapter>();
var table = new Mock<Foo.FooDataTable>();
var rows = new Mock<DataRowCollection>();
var row = new Mock<Foo.FooRow>();
rows.Setup(x => x.GetEnumerator().Current).Returns(row.Object);
table.Setup(x => x.Rows).Returns(rows.Object);
adapter.Setup(x => x.GetFooByID(1)).Returns(table.Object);
_adapter = adapter.Object;
If I don't try to add the row, I get a NullReferenceException in the foreach. If I do try to add the row, I get a System.NotSupportedException: Type to mock must be an interface or an abstract or non-sealed class.
Mocks are awesome and all but they really are testing tools of last resort -- what you reach for when you've got some impossible to create object you can't avoid depending on -- such as HttpContext.
In this case, you probably don't want to create a moq mock of the DataTable -- you can just new up one with appropriate data. What you'd want to moq mock would be the call to Adapter.GetFooById() to spit back your test double of a data table.
Mocks should only be used to create fake dependencies when you want to test the behaviour of something that requires said dependency, but you don't want (or can't) actually create a "real" instance of that dependency. Any test method with more than a couple of mocks is headed in the wrong direction because it's a sign that you have either too many dependencies, or that you are testing too many unrelated things.
In the code you have above, there are no dependencies, so Mocks wouldn't be appropriate really what you need.
You really need to think about what exactly it is you are trying to test here. For the sake of argument let's assume that the code you showed is from a method:
public class MyFooClass
{
public int DoFooFooData(FooAdapter Foo)
{
Data.Foo.FooDataTable tbl = Adapter.GetFooByID(id);
//just imagining what you might do here.
int total=0;
foreach (Data.Foo.FooRow row in tbl)
{
x = row.bar
//just imagining what you might do here.
total+=x;
}
return total;
}
}
Now, let's further suppose that you want to unit test this method. In this case in order to call the method you have to supply a working FooAdapter instance because the method depends on it in order to work
But let's now say that you are not currently in possession of a FooAdapter because it doesn't exist, or maybe you can't supply one because FooAdapter makes a database connection which is a no-no in unit testing.
What we need to do in order to test DoFooFooData is to supply a fake (Mock) FooAdapter, which only implements the GetFooByID method, in order for your function to execute.
To do this you'll have to either make FooAdapter abstract or (I recommend) declare it by interface:
public interface IFooAdapter
{
Data.Foo.FooDataTable GetByID(int id);
}
(later on you'll need to change FooAdapter class to implement IFooAdapter if you want to actually use it with the DoFooFooData method for real)
Now change your method signature:
public void DoFooFooData(IFooAdapter Foo)
{
Data.Foo.FooDataTable tbl = Adapter.GetFooByID(id);
int total=0;
foreach (Data.Foo.FooRow row in tbl)
{
x = row.bar
//just imagining what you might do here
total+=x;
}
return total;
}
And finally in your test method, you can mock this dependency:
void DoFooFooData_DoesSomeFooAndReturns3()
{
var mock = new Mock<IFooAdapter>();
var table = new Data.Foo.FooDataTable();
table.Add(new Data.Foo.FowRow{bar=1});
table.Add(new Data.Foo.FowRow{bar=2});
mock.Setup(m=>m.GetByID(It.IsAny<int>()).Returns(table);
var sut = new MyFooClass();
var expected=3;
var actual=sut.DoFooFooData(mock.Object);
Assert.AreEqual(expected,actual);
}
Of course if you need to Mock FooDataTable as well you can follow the same pattern as you did with the IFooAdapter but you need to stop at this point and ask yourself if you shouldn't be creating a separate test in which you Mock an IFooDataTable and ensure that it does what it's supposed to do (Add method or whatever) and so on...at the point when you were sure that the behavioural contract of IFooDataTable is OK, you'd then implement it as a concrete "stub" which you can then use in place of any FooDataTable references in the context of an IFooAdapter...but now you're into integration tests which is a story for another day...

Fluentvalidation - tie validation to specific process best practice

what would be the best practice for tying validation rules to specific process using http://fluentvalidation.codeplex.com/
Currently I'm using "Rule Sets" feature to group rules to different processes:
public class ObjAValidation: AbstractValidator<A>
{
public ObjAValidation()
{
RuleSet("ProcessA", () =>
{
RuleFor(x => ...);
RuleFor(x => ...);
});
RuleSet("ProcessB", () =>
{
RuleFor(x => ...);
RuleFor(x => ...);
});
}
}
And then validate using:
var a = new A(){...};
IValidator<A> validator = new ObjAValidation();
var result = validator.Validate(a, ruleSet: "ProcessA");
I have two problems with this approach:
I don't like to use strings as process names. I would like to use a
more strongly typed approach. For example to be able to use marker
interfaces or attributes.
In my Unit tests I can't setup the Validate method of IValidator
because you can't use optional arguments with Moq.
Mock<IValidator<A>> _mockValidator = new Mock<IValidator<A>>();
_mockValidator.Setup(x => x.Validate(new A(), ruleSet: "ProcessA"));
Second line generates a run time error: An expression tree may not contain a named argument specification. And if you want to pass the ruleSet argument without a named argument to Validate method you have to provide a "IValidatorSelector selector" object. But this interface is not documented.
What prevents you to create a helper class where you can use variables, data structures, anything you like to prevent the usage of hard-coded string parameters? Also, don't forget the possibility of using enums.
What prevents you from creating a class which implements IValidator where you can also implement custom functionality needed by you?
I have encountered the same issue and found out the reason why you can not mock this method via Moq etc validator.Validate(a, ruleSet: "ProcessA"); is because it is an extension method and Moq can't mock static methods.
Someone raised the same issue here in the FluentValidation issues: https://github.com/JeremySkinner/FluentValidation/issues/191
The simple solution is not to use the extension method rather use the instant method IValidator.validate(context). All you need to do is to build the context. Check out the source code from here: https://github.com/JeremySkinner/FluentValidation/blob/master/src/FluentValidation/DefaultValidatorExtensions.cs#L819
if(ruleSet != null) {
var ruleSetNames = ruleSet.Split(',', ';').Select(x => x.Trim());
selector = ValidatorOptions.ValidatorSelectors.RulesetValidatorSelectorFactory(ruleSetNames.ToArray());
}
var context = new ValidationContext<T>(instance, new PropertyChain(), selector);
return validator.Validate(context);

Using Moq to verify calls are made in the correct order

I need to test the following method:
CreateOutput(IWriter writer)
{
writer.Write(type);
writer.Write(id);
writer.Write(sender);
// many more Write()s...
}
I've created a Moq'd IWriter and I want to ensure that the Write() methods are called in the right order.
I have the following test code:
var mockWriter = new Mock<IWriter>(MockBehavior.Strict);
var sequence = new MockSequence();
mockWriter.InSequence(sequence).Setup(x => x.Write(expectedType));
mockWriter.InSequence(sequence).Setup(x => x.Write(expectedId));
mockWriter.InSequence(sequence).Setup(x => x.Write(expectedSender));
However, the second call to Write() in CreateOutput() (to write the id value) throws a MockException with the message "IWriter.Write() invocation failed with mock behavior Strict. All invocations on the mock must have a corresponding setup.".
I'm also finding it hard to find any definitive, up-to-date documentation/examples of Moq sequences.
Am I doing something wrong, or can I not set up a sequence using the same method?
If not, is there an alternative I can use (preferably using Moq/NUnit)?
There is bug when using MockSequence on same mock. It definitely will be fixed in later releases of Moq library (you can also fix it manually by changing Moq.MethodCall.Matches implementation).
If you want to use Moq only, then you can verify method call order via callbacks:
int callOrder = 0;
writerMock.Setup(x => x.Write(expectedType)).Callback(() => Assert.That(callOrder++, Is.EqualTo(0)));
writerMock.Setup(x => x.Write(expectedId)).Callback(() => Assert.That(callOrder++, Is.EqualTo(1)));
writerMock.Setup(x => x.Write(expectedSender)).Callback(() => Assert.That(callOrder++, Is.EqualTo(2)));
I've managed to get the behaviour I want, but it requires downloading a 3rd-party library from http://dpwhelan.com/blog/software-development/moq-sequences/
The sequence can then be tested using the following:
var mockWriter = new Mock<IWriter>(MockBehavior.Strict);
using (Sequence.Create())
{
mockWriter.Setup(x => x.Write(expectedType)).InSequence();
mockWriter.Setup(x => x.Write(expectedId)).InSequence();
mockWriter.Setup(x => x.Write(expectedSender)).InSequence();
}
I've added this as an answer partly to help document this solution, but I'm still interested in whether something similar could be achieved using Moq 4.0 alone.
I'm not sure if Moq is still in development, but fixing the problem with the MockSequence, or including the moq-sequences extension in Moq would be good to see.
I wrote an extension method that will assert based on order of invocation.
public static class MockExtensions
{
public static void ExpectsInOrder<T>(this Mock<T> mock, params Expression<Action<T>>[] expressions) where T : class
{
// All closures have the same instance of sharedCallCount
var sharedCallCount = 0;
for (var i = 0; i < expressions.Length; i++)
{
// Each closure has it's own instance of expectedCallCount
var expectedCallCount = i;
mock.Setup(expressions[i]).Callback(
() =>
{
Assert.AreEqual(expectedCallCount, sharedCallCount);
sharedCallCount++;
});
}
}
}
It works by taking advantage of the way that closures work with respect to scoped variables. Since there is only one declaration for sharedCallCount, all of the closures will have a reference to the same variable. With expectedCallCount, a new instance is instantiated each iteration of the loop (as opposed to simply using i in the closure). This way, each closure has a copy of i scoped only to itself to compare with the sharedCallCount when the expressions are invoked.
Here's a small unit test for the extension. Note that this method is called in your setup section, not your assertion section.
[TestFixture]
public class MockExtensionsTest
{
[TestCase]
{
// Setup
var mock = new Mock<IAmAnInterface>();
mock.ExpectsInOrder(
x => x.MyMethod("1"),
x => x.MyMethod("2"));
// Fake the object being called in order
mock.Object.MyMethod("1");
mock.Object.MyMethod("2");
}
[TestCase]
{
// Setup
var mock = new Mock<IAmAnInterface>();
mock.ExpectsInOrder(
x => x.MyMethod("1"),
x => x.MyMethod("2"));
// Fake the object being called out of order
Assert.Throws<AssertionException>(() => mock.Object.MyMethod("2"));
}
}
public interface IAmAnInterface
{
void MyMethod(string param);
}
The simplest solution would be using a Queue:
var expectedParameters = new Queue<string>(new[]{expectedType,expectedId,expectedSender});
mockWriter.Setup(x => x.Write(expectedType))
.Callback((string s) => Assert.AreEqual(expectedParameters.Dequeue(), s));
Recently, I put together two features for Moq: VerifyInSequence() and VerifyNotInSequence(). They work even with Loose Mocks. However, these are only available in a moq repository fork:
https://github.com/grzesiek-galezowski/moq4
and await more comments and testing before deciding on whether they can be included in official moq releaase. However, nothing prevents you from downloading the source as ZIP, building it into a dll and giving it a try. Using these features, the sequence verification you need could be written as such:
var mockWriter = new Mock<IWriter>() { CallSequence = new LooseSequence() };
//perform the necessary calls
mockWriter.VerifyInSequence(x => x.Write(expectedType));
mockWriter.VerifyInSequence(x => x.Write(expectedId));
mockWriter.VerifyInSequence(x => x.Write(expectedSender));
(note that you can use two other sequences, depending on your needs. Loose sequence will allow any calls between the ones you want to verify. StrictSequence will not allow this and StrictAnytimeSequence is like StrictSequence (no method calls between verified calls), but allows the sequence to be preceeded by any number of arbitrary calls.
If you decide to give this experimental feature a try, please comment with your thoughts on:
https://github.com/Moq/moq4/issues/21
Thanks!
I've just had a similar scenario, and inspired by the accepted answer, I've used the following approach:
//arrange
var someServiceToTest = new SomeService();
var expectedCallOrder = new List<string>
{
"WriteA",
"WriteB",
"WriteC"
};
var actualCallOrder = new List<string>();
var mockWriter = new Mock<IWriter>();
mockWriter.Setup(x => x.Write("A")).Callback(() => { actualCallOrder.Add("WriteA"); });
mockWriter.Setup(x => x.Write("B")).Callback(() => { actualCallOrder.Add("WriteB"); });
mockWriter.Setup(x => x.Write("C")).Callback(() => { actualCallOrder.Add("WriteC"); });
//act
someServiceToTest.CreateOutput(_mockWriter.Object);
//assert
Assert.AreEqual(expectedCallOrder, actualCallOrder);
Moq has a little-known feature called Capture.In, which can capture arguments passed to a method. With it, you can verify call order like this:
var calls = new List<string>();
var mockWriter = new Mock<IWriter>();
mockWriter.Setup(x => x.Write(Capture.In(calls)));
CollectionAssert.AreEqual(calls, expectedCalls);
If you have overloads with different types, you can run the same setup for overloads too.
My scenario was methods without parameters:
public interface IWriter
{
void WriteA ();
void WriteB ();
void WriteC ();
}
So I used Invocations property on the Mock to compare what was called:
var writer = new Mock<IWriter> ();
new SUT (writer.Object).Run ();
Assert.Equal (
writer.Invocations.Select (invocation => invocation.Method.Name),
new[]
{
nameof (IWriter.WriteB),
nameof (IWriter.WriteA),
nameof (IWriter.WriteC),
});
You could also append the invocation.Arguments to check method calls with parameters.
Also the failure message is more clear than just expected 1 but was 5:
expected
["WriteB", "WriteA", "WriteC"]
but was
["WriteA", "WriteB"]
I suspect that expectedId is not what you expect.
However i'd probably just write my own implementation of IWriter to verify in this case ... probably a lot easier (and easier to change later).
Sorry for no Moq advice directly. I love it, but haven't done this in it.
do you maybe need to add .Verify() at the end of each setup? (That really is a guess though i'm afraid).
I am late to this party but I wanted to share a solution that worked for me since it seems as though all of the referenced solutions did not work with verifying the same method call (with the same arguments) multiple times in order. In addition the referenced bug, Moq Issue #478 was closed without a solution.
The solution presented utilizes the MockObject.Invocations list to determine order and sameness.
public static void VerifyInvocations<T>(this Mock<T> mock, params Expression<Action<T>>[] expressions) where T : class
{
Assert.AreEqual(mock.Invocations.Count, expressions.Length,
$"Number of invocations did not match expected expressions! Actual invocations: {Environment.NewLine}" +
$"{string.Join(Environment.NewLine, mock.Invocations.Select(i => i.Method.Name))}");
for (int c = 0; c < mock.Invocations.Count; c++)
{
IInvocation expected = mock.Invocations[c];
MethodCallExpression actual = expressions[c].Body as MethodCallExpression;
// Verify that the same methods were invoked
Assert.AreEqual(expected.Method, actual.Method, $"Did not invoke the expected method at call {c + 1}!");
// Verify that the method was invoked with the correct arguments
CollectionAssert.AreEqual(expected.Arguments.ToList(),
actual.Arguments
.Select(arg =>
{
// Expressions treat the Argument property as an Expression, do this to invoke the getter and get the actual value.
UnaryExpression objectMember = Expression.Convert(arg, typeof(object));
Expression<Func<object>> getterLambda = Expression.Lambda<Func<object>>(objectMember);
Func<object> objectValueGetter = getterLambda.Compile();
return objectValueGetter();
})
.ToList(),
$"Did not invoke step {c + 1} method '{expected.Method.Name}' with the correct arguments! ");
}
}

How to mock Add method of subsonic's SimpleRepository

I'm trying to mock the Add method of subsonic SimpleRepository with Rihino mocks, I'm using the IRepository Interface but I'm new to mocking and dont know how to go from there, can this be done? thanks for your help.
AdamRalph is correct, but I prefer the AAA syntax of Rhino Mocks:
// arrange
var repo = MockRepository.GenerateStub<IRepository>();
var myObject = CreateSampleObject();
repo.Stub(r => r.Add(myObj)).Return(myObj);
// act (this assumes that the call to "SomeMethod" on "SomeClass"
// returns the result of the IRepository.Add).
var someClass = new SomeClass(repo);
var result = someClass.SomeMethod();
// assert
Assert.AreSame(myObject, result);
It depends what you want to test. Do you care if the Add() method is called or not, or do you just want to set up a canned response which may or may not be called?
If you expect the call:-
var mocks = new MockRepository();
var repo = mocks.StrictMock<IRepository>():
var myObj = CreateSampleObject();
using(mocks.Record())
{
Expect.Call(repo.Add(myObj)).Return(myObj);
}
using(mocks.Playback())
{
var target = CreateTarget(repo);
target.DoSomething(myObj);
}
If you don't care whether it is called or not, then use SetUpResult instead of Expect, e.g.
SetUpResult.For(rep.Add(myObj)).Return(myObj);

Categories