Mocking a method on a property - c#

I need to set the return value for a method returned by a property, basically I need to set what this does:
mockedObject.TheProperty.GetTheValues()
I just need it to return Enumerable.Empty<MyType>.

For the purposes of demonstrating that the functionality exists assuming
public interface IFoo {
IBar TheProperty { get; set; }
}
public interface IBar {
IEnumerable<MyType> GetTheValues();
}
public class MyType { }
Moq allows for auto mocking hierarchies otherwise known as recursive mocks
[TestClass]
public class RecursiveMocksTests {
[TestMethod]
public void Foo_Should_Recursive_Mock() {
//Arrange
IEnumerable<MyType> expected = Enumerable.Empty<MyType>();
var mock = new Mock<IFoo>();
// auto-mocking hierarchies (a.k.a. recursive mocks)
mock.Setup(_ => _.TheProperty.GetTheValues()).Returns(expected);
var mockedObject = mock.Object;
//Act
IEnumerable<MyType> actual = mockedObject.TheProperty.GetTheValues();
//Assert
actual.Should().BeEquivalentTo(expected);
}
}
Note that at no point was IBar ever initialized or configured. The framework will auto mock that interface because of the setup shown above.
If however, more functionality is needed from an IBar, then a proper mock should be done and configured accordingly. There is also nothing stopping the use of configuring multiple IBar members via the IFoo mock.
Reference Moq Quickstart: Properties

Imagine you have this:
public interface IA
{
IEnumerable<MyType> TheProperty { get; set; }
}
public class MyType {}
Then here is how to mock it so when TheProperty is called, it returns and IEnumerable.Empty<MyType>:
[TestMethod]
public void SomeTest()
{
/* Arrange */
var iAMock = new Mock<IA>();
iAMock.Setup(x => x.TheProperty).Returns(Enumerable.Empty<MyType>());
/* Act */
/* Assert */
}

Related

Mocking a concrete class with a virtual method

I want to test a class that depends on another class with the virtual method.
class DepClass
{
public virtual string Get() => "";
}
class HostClass
{
private _c;
public Host(DepClass c){ _c = c; }
public string Magic() => _c.Get();
}
Now I want to test the HostClass with Autofixture + NSubstitute.
My expectation:
Fixture.Freeze<DepClass>().Get().ReturnsForAnyArg("123");
var sut = Fixture.Create<HostClass>();
var res = sut.Magic(); //should be 123
As a fact, when I do Freeze().Get().Returns() the real Get method is being called.
How to customize Autofixture to mock all virtual methods?
Would be great not to discuss interface vs virtual methods, etc
Update
This does not work:
Fixture.Freeze<DepClass>().Get().ReturnsForAnyArgs("123");
At the same time, this works:
Substitute.For<DepClass>().Get().ReturnsForAnyArgs("123");
In addition to the answer
Another approach that might be not fit your needs: in my case, I expect that only direct dependencies can have virtual methods. all dependencies of the lower level will be mocked.
As result, I decided to go in a bit more specific way. The code below is an example, so you might be want to modify it before using it in your solution.
abstract class UnitTestBase<T>
{
protected IFixture Fixture { get; private set; }
protected IList<Type> ProxyTypes {get; private set;}
protected CreateSut(): T => Fixt.Create<T>();
[SetUp]
protected virtual Setup()
{
ProxyTypes = new List<Type>();
Fixture = new Fixture().Customize(new CompositeCustomization(
new AutoNSubstituteCustomization {
ConfigureMembers = true,
GenerateDelegates = true
})
);
SetupTypesToProxy();
Fixture.Customizations.Add(new SubstituteRelay(new ProxyExactTypesSpecification(ProxyTypes)));
}
protected virtual void SetupTypesToProxy()
=> typeof(T)
.GetConstructors(BindingFlags.Public | BindingFlags.Instance)
.SelectMany(ctorInfo => ctorInfo
.GetParameters()
.Select(paramInfo => paramInfo.ParameterType)
.Where(ShouldProxy))
.ForEach(t => ProxyTypes.Add(t));
private static bool ShouldProxy(Type type)
=> !type.GetTypeInfo().IsInterface && !type.GetTypeInfo().IsAbstract;
}
internal class ProxyExactTypesSpecification: IRequestSpecification
{
public ProxyExactTypesSpecification(
IEnumerable<Type> types
)
{
_proxyTypes = types ?? Type.EmptyTypes;
}
public bool IsSatisfiedBy(
object request
)
{
Argument.NotNull(request, nameof(request));
if (request is Type type)
return _proxyTypes.Contains(type);
return false;
}
private readonly IEnumerable<Type> _proxyTypes;
}
Because DepClass is neither an interface nor an abstract type, by default, AutoFixture will not rely on a mocking framework to create the instance, and will use the actual constructor from the type.
Since NSubstitute does not have the equivalent of Mock<T> or Fake<T> from other popular mocking frameworks, AutoFixture had to provide a special specimen builder, called SubstituteRelay, to fill in the gap. You can use this class as any other specimen builder to instruct the Fixture to return a mock when a specific type instance is requested.
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
fixture.Customizations
.Add(new SubstituteRelay(new ExactTypeSpecification(typeof(DepClass))));
This construction is a bit lengthy so you could create a generic relay to shorten the syntax.
public class SubstituteRelay<T> : CompositeSpecimenBuilder
{
public SubstituteRelay()
: base(new SubstituteRelay(new ExactTypeSpecification(typeof(T))))
{
}
}
You should be able to write your test something like.
[Fact]
public void ReturnsExpectedValue()
{
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
fixture.Customizations.Add(new SubstituteRelay<DepClass>());
fixture.Freeze<DepClass>().Get().ReturnsForAnyArgs("1234");
var sut = fixture.Create<HostClass>();
var actual = sut.Magic();
Assert.Equal("1234", actual);
}
To get closer to your intended API, you can create your own extension method that abstracts away the two lines of code that register the relay and freeze the instance.

Unit test with multiple interfaces

I have Web API project with the following service class called from API Controller. I want to write unit testcase for the below class using Moq framework. How can I construct multiple interfaces using Moq? If its not possible using Moq, is there any other framework?
public class MyService : IMyService
{
private readonly IInterface1 _interface1;
private readonly IInterfaces2 _interface2;
private readonly IInterface3 _interface3;
public MyService(IInterface1 interface1,IInterface2 interface2,IInterface3 interface3)
{
_interface1=interface1;
_interface2=interface2;
_interface3=interface3;
}
public SomeModel MyMethod1(1Model model)
{
//do something here....
}
public SomeMode2 MyMethod2(Model2 model)
{
//do something here....
}
public SomeMode3 MyMethod3(Model3 model)
{
//do something here....
}
}
Imagine you have these interfaces:
public interface IOne
{
int Foo();
}
public interface ITwo
{
int Foo(string str);
}
And you have a class which depends on above interfaces:
public class Some
{
private readonly IOne one;
private readonly ITwo two;
public Some(IOne one, ITwo two)
{
this.one = one;
this.two = two;
}
public void Work()
{
// Uses one and two
}
}
And now you want to test the Work() method and you want to mock the dependencies, here is how:
// Arrange
// Let's set up a mock for IOne so when Foo is called, it will return 5
var iOneMock = new Mock<IOne>();
iOneMock.Setup(x => x.Foo()).Returns(5);
// Let's set up the mock for ITwo when Foo is called with any string,
// it will return 1
var iTwoMock = new Mock<ITwo>();
iTwoMock.Setup(x => x.Foo(It.IsAny<string>())).Returns(1);
var some = new Some(iOneMock.Object, iTwoMock.Object);
// Act
some.Work();
// Assert
// Let's verify iOneMock.Foo was called.
iOneMock.Verify(x => x.Foo());
// Let's verify iTwoMock.Foo was called with string "One" and was called only once
iTwoMock.Verify(x => x.Foo("One"), Times.Once());
In my example above I tried to show methods which take an argument, methods which take no argument, verifying method was called and verify method was called once. That should give you and idea of the options available. There are many other options available. Please see the Moq documentation for more.
You can use AutoMoq to solve the dependency injections.
var mocker = new AutoMoqer();
var myService = mocker.Create<MyService>();
var interface1 = mocker.GetMock<IInterface1>();

Testing different concrete implementations of single interface?

I have the following code:
public interface IFoo
{
IResult ResolveTheProblem(IBar inputData);
}
public class FastFoo : IFoo
{
public IResult ResolveTheProblem(IBar inputData)
{
// Algorithm A - resolves the problem really fast
}
}
public class SlowFoo : IFoo
{
public IResult ResolveTheProblem(IBar inputData)
{
// Algorithm B - different algoritm, resolves the problem slow
}
}
The most important thing to test is implementation of each algorithm.
For testing I'm using NUnit and NSubstitute. Right now I have test like this:
[Test]
public void FooTest()
{
IFoo foo = Substitute.For<IFoo>();
IBar bar = Substitute.For<IBar>();
IResult result = foo.ResolveTheProblem(bar);
Assert.IsNotNull(result);
}
My two questions:
Is that test even necessary? I'm not sure about that
How can I test implementation of each IFoo (FastFoo and SlowFoo)?
EDIT: FastFoo and SlowFoo are two completely different implementations. The result of both is a random number from 1 to 10.
No, it's not necessary. Why would you want to test a substitute implementation?
You substitute your dependencies, like IBar.
You test your concrete implementations:
[Test]
public void SlowFooTest()
{
IBar bar = Substitute.For<IBar>();
// Setup bar expectations / canned responses as required
var foo = new SlowFoo(bar);
IResult result = foo.ResolveTheProblem(bar);
// Validate result from concrete class:
Assert.IsNotNull(result);
}
[Test]
public void FastFooTest()
{
IBar bar = Substitute.For<IBar>();
var foo = new FastFoo(bar);
IResult result = foo.ResolveTheProblem(bar);
Assert.IsNotNull(result);
}
Is that test even necessary? I'm not sure about that
That test does not appear to do anything. You appear to be creating a test double for the service under test.
How can I test implementation of each IFoo (FastFoo and SlowFoo)?
Is the answer always going to be the same for FastFoo and SlowFoo, or does FastFoo trade accuracy for speed?
If they are always the same then inheritance. Create a base FooTest with an abstract CreateFoo. Then two concrete implementations.
If they are not always the same, then again inheritance but with a fuzzy element.
abstract class AbstractFooTester {
[Test]
public void WhenBarIsSomethingThenResultIsSomethingElse() {
var mockRandomNumberGenerator = createRandomNumberMock(5);
var mockBar = Substitute.For<IBar>();
// set up Bar
...
var subject = createFoo(mockRandomNumberGenerator);
IResult result = subject.ResolveTheProblem(bar);
AssertResult(result, ...);
}
abstract Foo createFoo(RandomNumberGenertor g);
RandomNumberGenertor createRandomNumberMock(Int i) { ... }
}
class TestFastFoo extends AbstractFooTester {
Foo createFoo(RandomNumberGenertor g) { return new FastFoo(g); }
}
class TestSlowFoo extends AbstractFooTester {
Foo createFoo(RandomNumberGenertor g) { return new SlowFoo(g); }
}

Original method still getting called in Moq even after CallBase = true/false

Here's my code:
public class Bar { }
public class Foo { public string Name { get; set; } public Bar TheBar { get; set; } }
public class Dependency
{
public Foo DoSomething(Expression<Func<Foo, bool>> exp1) { return new Foo(); }
}
public class Base
{
public Dependency Dependency { get; set; }
public virtual Foo MethodA(Expression<Func<Foo, bool>> exp1,
params Expression<Func<Foo, object>>[] exp2)
{
return Dependency.DoSomething(exp1);
}
}
public class Derived : Base
{
public Foo DerviedMethod(string str)
{
return base.MethodA(e1 => e1.Name.Equals(str), e2 => e2.TheBar);
}
}
And my Unit Test code:
var mock = new Mock<Derived> { CallBase = true }; // Same result with false
mock
.Setup(m => m.MethodA(
It.IsAny<Expression<Func<Foo, bool>>>(),
It.IsAny<Expression<Func<Foo, object>>>()
))
.Returns(new Foo());
// Act
var result = mock.Object.DerviedMethod("test");
// Assert
Assert.IsNotNull(result);
But it still calls the original method and not the mocked one. Both classes exist in same assembly.
I have searched about it and almost all people got it right with CallBase = true or false.
Any ideas what is wrong with above code?
As has been suggested by #Pierre-Luc in the comments, extracting the base class and injecting it as a dependency is probably the better approach (I always think mocking the class you're actually trying to test feels wrong).
That said, for you to be able to mock a call of a class, it needs to be made via the VTable. Essentially, the mocking framework creates a new implementation of the virtual method. When you call it normally, this version of the method is run and can then intercept calls. The problematic line is this one:
return base.MethodA(e1 => e1.Name.Equals(str), e2 => e2.TheBar);
Because you're explicitly calling MethodA, via the base keyword, it tells the compiler to call a particular version of the method. It's always going to call the base implementation. This means that the mock can't intercept the call.
Changing the method to:
public Foo DerviedMethod(string str) {
return MethodA(e1 => e1.Name.Equals(str), e2 => e2.TheBar);
}
Allows the MethodA method to be mocked. Whether or not this is the right thing from a design perspective is up to you.

Why do Rhino.Mocks and Moq say that Bar is a non-overridable member?

Could someone explain why both tests using the latest versions of Moq and Rhino.Mocks frameworks fail complaining that Bar is not a virtual/overridable method:
public interface IFoo
{
string Bar();
}
public class Foo : IFoo
{
public string Bar()
{
return "Bar";
}
}
[TestMethod]
public void MoqTest()
{
var foo = new Mock<Foo>();
foo.Setup(f => f.Bar()).Returns("abc");
Assert.AreEqual("abc", foo.Object.Bar());
}
[TestMethod]
public void RhinoTest()
{
var foo = new MockRepository().PartialMock<Foo>();
foo.Expect(f => f.Bar()).Return("abc");
foo.Replay();
Assert.AreEqual("abc", foo.Bar());
}
If I declare Bar method as virtual both tests pass. I don't understand why I have to declare Bar as virtual. Isn't it already virtual? It comes from the interface.
Virtual is part of the class not the interface, so if you wish to override the method on the class Foo you will need to declare it as virtual.
However as Krzysztof mentions if all you need are the methods on the interface IFoo then you should mock the interface.
Because you're mocking Foo class.
Mock IFoo intefrace instead
var foo = new MockRepository().PartialMock<IFoo>();

Categories

Resources