I am using NUnit, Moq and StructureMap.
I have a following NUnit test:
[Test]
public void ShouldCallCustomMethod_ForAllICustomInterfaceMocks()
{
var customInterfaceMock1 = new Mock<ICustomInterface>();
var customInterfaceMock2 = new Mock<ICustomInterface>();
ObjectFactory.Inject(customInterfaceMock1.Object);
ObjectFactory.Inject(customInterfaceMock2.Object);
var sut = new SUT();
sut.MethodThatShouldCallCustomMethodOnMocks();
customInterfaceMock1.Verify(m => m.CustomMethod());
customInterfaceMock2.Verify(m => m.CustomMethod());
}
ICustomInterface:
public interface ICustomInterface
{
IEnumerable<Type> CustomMethod();
}
Now if implementation of SUT class looks like this:
public class SUT
{
public IEnumerable<Type> MethodThatShouldCallCustomMethodOnMocks()
{
var result = ObjectFactory.GetAllInstances<ICustomInterface>()
.SelectMany(i => i.CustomMethod());
return result;
}
}
test from above fails due to method CustomMethod not being called on mocks.
However, if I change implementation of SUT class to this:
public class SUT
{
public IEnumerable<Type> MethodThatShouldCallCustomMethodOnMocks()
{
var customInterfaceInstances = ObjectFactory.GetAllInstances<ICustomInterface>();
foreach (var instance in customInterfaceInstances)
instance.CustomMethod();
return ...
}
}
test passes!
The difference is that instead of iterating with SelectMany i use foreach, but test results differ (in second case CustomMethods do get called on mocks).
Can somebody explain that behaviour?
I think this might be a case of deferred execution. SelectMany doesn't execute immediately. The IEnumerable that's returned must be enumerated for your methods to be called. Try adding ToList() after the SelectMany() method to force the IEnumerable returned from SelectMany to be evaluated.
Related
I would like to test if function received a specific delegate as parameter. Is it possible in NUnit with NSubstitute?
My interface:
public interface IMyInterface
{
void Sort(Func<IEnumerable<int>, IOrderedEnumerable<int>> f);
}
My test class:
[TestFixture]
public class Class1
{
[Test]
public void Sort_WhenCalled_CallsWithPassedArgument()
{
// Arrange
IMyInterface mock = Substitute.For<IMyInterface>();
// Act
mock.Sort(x => x.OrderBy(y => y));
// Assert
mock.Received().Sort(x => x.OrderBy(y => y));
}
}
I also tried with argument matchers, but it always fails.
The challenge is that your argument type is Func<>, not Expression<Func<>>. With Expression you could inspect the tree to check method names etc.
However, you can unit test against the concrete example for OrderBy (e.g. as opposed to OrderByDescending(), because given a collection of ints 6,4 OrderBy() will always re-sort it to be 4,6. So the following works:
[TestFixture]
public class Class1
{
[Test]
public void Sort_WhenCalled_CallsWithPassedArgument()
{
// Arrange
IMyInterface mock = Substitute.For<IMyInterface>();
Func<IEnumerable<int>, IOrderedEnumerable<int>> func = null;
mock.WhenForAnyArgs(x => x.Sort(Arg.Any<Func<IEnumerable<int>, IOrderedEnumerable<int>>>())).Do(
x =>
{
func = x.Arg<Func<IEnumerable<int>, IOrderedEnumerable<int>>>();
});
// Act
mock.Sort(x => x.OrderBy(y => y));
// Assert
var result = func(new[] { 6, 4 });
Assert.That(result.FirstOrDefault(), Is.Not.EqualTo(6));
Assert.That(result.FirstOrDefault(), Is.EqualTo(4));
}
}
Of course, the logic is somewhat fragile, so you need to decide if you really want to test that an exact method is used in a func (and then maybe refactor the code to allow to check for this specific method by other means or switch to Expression) or just the behaviour is enough for you.
I have the following interface that I want to mock:
public interface ISomeInterface
{
string GiveMe(Expression<Func<Person, bool>> predicate);
}
With the following Poco:
public class Person
{
public string Name { get; set; }
}
Then I am setting up my mock as:
[Test]
public void Run()
{
var expectedPredicate = It.IsAny<Expression<Func<Person, bool>>>();
var mock = new Mock<ISomeInterface>(MockBehavior.Strict);
mock
.Setup(m => m.GiveMe(expectedPredicate))
.Returns("Yo!");
var message = mock.Object.GiveMe(p => p.Name == string.Empty); // throws
}
But I am getting:
Invocation failed with mock behavior Strict. All invocations on the
mock must have a corresponding setup.
What am I missing here?
Don't assign the result of It.IsAny to an intermediate variable, use it inline:
mock.Setup(m => m.GiveMe(It.IsAny<Expression<Func<Person, bool>>>()))
.Returns("Yo!");
If you look at the Setup method, it actually takes an Expression parameter, Moq analyses this to determine what your intention is, by assigning the result of It.IsAny to an intermediate variable, Moq will not see the MethodCallExpression it is capable of understanding and instead will see a MemberExpression.
This results in Moq actually performing an equality comparison between the actual parameter and expectedPredicate variable rather than the It.IsAny check.
Given:
public static void GetAllTypesInContainer<t>(AContainerWithChildren bw)
{
var list = new List<t>();
var stuff = bw.GetChildren();
foreach (var child in stuff)
{
if (child.GetType().Name == typeOf(t).Name)
{
list.Add((t)child);
}
}
}
How do I add values of that type to the list?
If I understand the code, you're trying to get all children of type t into a list, and ignoring the rest. Linq makes that easy. I'm assuming the result of calling bw.GetChildren() is enumerable based on your example.
using System.Linq;
// ...
private static List<T> GetAllTypesInContainer<T>(this Container bw)
{
var list = bw.GetChildren().OfType<T>().ToList();
return list;
}
Or for a version optimised to suit the fluent coding style the OP is after, keeping the context with the container:
private static Container ForEachChildOfType<T>(this Container bw, Action<T> action)
{
var children = bw.GetChildren().OfType<T>().ToList();
children.Do(action);
return bw;
}
// later to be used similar as follows as per OP's example
bw
.StoreInformation()
.ForEachChildOfType<HtmlHyperLink>(link =>
{
if (link.Href == "Something") // caution, watch for mixed case!!!
{
}
})
.AssertControlTitleOnHomePage();
NB As a general coding style I'd never call a method GetXXX unless it actually returned something, hence the name change.
ps. Hope there's no typos in there, this is all from memory!
The final solution was:
public static Container GetAllTypesInContainer<t>(this Container bw, Action<List<t>> Callback)
{
var list = new List<t>();
list= bw.GetChildren().OfType<t>().ToList();
Callback(list);
return bw;
}
The reason for the callbacks is in the design of the FLUID interface for the type Container. Callbacks allow me to return the static method instance type rather than the list, as a result I can chain all the activity and still process the content like this:
bw
.StoreInformation()
.GetAllHtmlHyperLinks((p) =>
{
p.ForEach((q) =>
{
if (q.Href == "Something")
{
}
});
})
.AssertControlTitleOnHomePage();
The callbacks allow me to process the results using anonymous methods.
I am writing unit tests for a series of similar methods defined on a single interface (this is a precursor to refactoring). I'm finding that similar code shows up in multiple methods:
// Each line here shows up in a different test method.
mock.Setup(m => m.MethodA()).Returns(() => true);
mock.Setup(m => m.MethodB()).Returns(() => true);
mock.Setup(m => m.MethodC()).Returns(() => true);
I would like to create a single method into which I can pass the method to be tested, but am at a loss how to do this. I'd like something that looks like this:
// testMethod is some method defined on IMyInterface.
private Mock<IMyInterface> SetupMockObject(Func<bool> testMethod)
{
var mock = new Mock<MyInterface>();
mock.Setup(m => m.testMethod()).Returns(() => true);
return mock;
}
The call to this method would then look something like:
var configuredMockObject = SetupMockObject(MethodA);
Is this possible?
EDIT: An expression tree appears to be what I need - previously I didn't get the concept that you could pass lambda expressions around. I've pasted the solution below since it took me a bit of fiddling to figure this out, although both dBurner's and Servy's answers proved helpful.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Moq.Language.Flow;
using System;
using System.Linq.Expressions;
namespace ExampleTest
{
[TestClass]
public class TestClass
{
private Mock<IMyInterface> _mock;
private interface IMyInterface
{
bool MethodA();
bool MethodB();
}
private ISetup<IMyInterface, bool> SetupMockObject(Expression<Func<IMyInterface,bool>> lambda)
{
var mockSetup = _mock.Setup(lambda);
return mockSetup;
}
[TestInitialize]
public void Setup()
{
_mock = new Mock<IMyInterface>();
}
[TestMethod]
public void TestMethodA()
{
SetupMockObject(i => i.MethodA()).Returns(true);
// Proceed with act and assert.
}
[TestMethod]
public void TestMethodB()
{
SetupMockObject(i => i.MethodB()).Returns(true);
// Proceed with act and assert.
}
}
}
The lambda that you pass to it needs to have a parameter of the mocked type, whereas your current parameter accepts a parameterless delegate:
public static Mock<MyInterface> SetupMockObject<T>(
Func<MyInterface, bool> testMethod)
{
var mock = new Mock<MyInterface>();
mock.Setup(testMethod).Returns(() => true);
return mock;
}
This allows you to write:
var mock = SetupMockObject(m => m.MethodA());
and have the code be equivalent to
var mock = new Mock<MyInterface>();
mock.Setup(m => m.MethodA()).Returns(() => true);
You can use expression trees for this. Your CommonTest method should have a Expression<Func<bool>> parameter.
With this parameter type you can get the method name. after this you should construct another Expression that will represent m => m.MethodFromParameter.
How would you go about faking the following:
public interface IBlah
{
Func<T, bool> ApplyFilter<T>(Func<T, bool> predicate) where T:IMessage;
}
What I would like is for the fake to simply return it's argument without any changes. However, I would like to verify that the fake has been called exactly once. A use case is given below:
public class Something
{
public Something(IBlah blah) { _blah = blah; }
public bool DoSomething(SomeValue m, Func<SomeValue, bool> predicate)
{
Func<SomeValue, bool> handler = _blah.ApplyFilter(predicate);
return handler(m);
}
}
i.e. the fake needs to act as a pass through but I also need to be able to verify it's been used.
What's the best way to go about this?
[Please don't worry about the contrived example...there's a lot of things going on under the covers, but I've simplified it down to the example above.]
Would this solve your issue? It will pass through the predicate and also verify that ApplyFilter was called exactly once
[Fact]
public void TestFeature()
{
var fake = A.Fake<IBlah>();
A.CallTo(() => fake.ApplyFilter(A<Func<int, bool>>.Ignored)).ReturnsLazily(x =>
{
return x.GetArgument<Func<int, bool>>("predicate");
});
var something = new Something(fake);
var result = something.DoSomething(1, x => x > 1);
Assert.False(result);
A.CallTo(() => fake.ApplyFilter(A<Func<int, bool>>.Ignored)).MustHaveHappened(Repeated.Exactly.Once);
}