I'm trying to do a simple test, mocking the sum method.
I have an interface:
public interface ISumSomething
{
int Sum(params int[] values);
}
A class that use this interface:
public class CallSum
{
public CallSum(ISumSomething sumSomething)
{
this.SumSomething = sumSomething;
}
private ISumSomething SumSomething { get; set; }
public int Execute(params int[] values)
{
return this.SumSomething.Sum(values);
}
}
And the test class:
[TestMethod]
public void Test_Sum_Method()
{
// Creates MOQ.
var instance = new Mock<ISumSomething>();
// Setup de MOQ.
instance.Setup(moq => moq.Sum(It.IsAny(1,2)).Returns(4));
// Instance the object.
var sum = new CallSum(instance.Object);
// Execute the operation.
var result = sum.Execute(2, 2);
// Check the result.
Assert.AreEqual(4, result);
}
The problem is, when I call the Execute method, it is returing 0, but in my MOQ, I'm setting 4. Why this happens?
In your Setup you say IsAny(1,2), those arguments don't match the arguments on Execute which are 2,2
You should instead be using:
instance.Setup(moq => moq.Sum(It.IsAny<int[]>()).Returns(4));
(See Setup Method With Params Array for more info)
Related
I want to mock only some methods of a class and call the real implementation for other methods.
I have my sut class Test where the Runner class is injected in the constructor. This injected class has again a injected other class RunnerParam in the constructor.
The code is a simplified case of my real classes in trying to have only the basics.
[Fact]
public void Test()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var paramMock = fixture.Freeze<Mock<IRunnerParam>>();
paramMock.Setup(x => x.Multiplicator()).Returns(2);
var classMock = fixture.Freeze<Mock<IRunner>>();
classMock.Setup(x => x.Run()).Returns(5);
var test = fixture.Create<Test>();
var result = test.StartRunning(); // should be 5
var result2 = test.StartRunningImplementation(5); // should be 500
}
Supporting members
public interface IRunnerParam
{
int Multiplicator();
}
public class RunnerParam : IRunnerParam
{
public virtual int Multiplicator()
{
return 20;
}
}
public interface IRunner
{
int Run();
int RunImplementation(int param);
}
public class Runner : IRunner
{
protected virtual RunnerParam MultiParam { get; set; }
public Runner(RunnerParam multiParam)
{
MultiParam = multiParam;
}
public virtual int Run()
{
return 10;
}
public int RunImplementation(int param)
{
return 10 * MultiParam.Multiplicator() * param * Run();
}
}
public class Test
{
private readonly IRunner _runner;
public Test(IRunner runner)
{
_runner = runner;
}
public int StartRunning()
{
return _runner.Run();
}
public int StartRunningImplementation(int param)
{
return _runner.RunImplementation(param);
}
}
I want to mock and give a mocked value to the method Run in the class Runner, but to use the real implementation of the method RunImplementation.
I would expect to see for result2 500, but it's 0, meaning that the method is not seen as mocked up. In my eyes that is correct, but the Moq callbase is equal to true, so the real implementation should be taken, but it isn't.
What am I missing here?
In the shown simplified example, Test is only dependent on IRunner
private readonly IRunner _runner;
public Test(IRunner runner)
{
_runner = runner;
}
So that is all that needs to be mocked if the intention was to test Test class in isolation.
//...
var classMock = fixture.Freeze<Mock<IRunner>>();
classMock.Setup(x => x.Run()).Returns(5);
classMock.Setup(x => x.RunImplementation(It.IsAny<int>())).Returns(500);
//...
If Runner class is to be also tested in isolation, then a mocked RunnerParam would be needed to satisfy its dependencies.
It should however be dependent on the abstraction (interface) and not the concretion (implementation).
protected virtual IRunnerParam MultiParam { get; set; }
public Runner(IRunnerParam multiParam) {
MultiParam = multiParam;
}
This simplifies the isolated test as described in the original question
I want to mock and give a mocked value to the method Run in the class Runner, but to use the real implementation of the method RunImplementation.
//Arrange
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var runnerParam = fixture.Freeze<Mock<IRunnerParam>>()
.Setup(_ => _.Multiplicator())
.Returns(2);
var subjectMock = fixture.Freeze<Mock<Runner>>();
subjectMock.CallBase = true;
subjectMock.Setup(_ => _.Run()).Returns(5);
int expected = 500;
Runner sut = subjectMock.Object;
//Act
var actual = sut.RunImplementation(5); // should be 500
//Assert
actual.Should().Be(expected);
I have a class library , which has 2 classes and one Interface as below.
Main Class:
public class Class1
{
int a=5 ,b=9;
private Interface1 iHelper;
public Class1(Interface1 _inter)
{
iHelper = _inter;
}
public int getData()
{
int result = iHelper.AddNumbers(a, b);
return result;
}
}
HelperClass Class :
class HelperClass : Interface1
{
public int AddNumbers(int a, int b)
{
return a + b;
}
}
Interface :
public interface Interface1
{
int AddNumbers(int a, int b);
}
Now, I'm trying to test the method getData(). I have mocked AddNumbers method using Moq , as shown below.
[TestMethod()]
public void getDataTest()
{
int a = 3, b = 5;
int c = 8;
var mockService = new Mock<Interface1>();
mockService.Setup(x => x.AddNumbers(a,b)).Returns(c);
Class1 obj = new Class1(mockService.Object);
var result = obj.getData();
int final = result;
}
When I debug this test, it is returning value 0.
As I understand when we mock any method, it has to return the mocked value while testing. In this case I have mocked the return value of AddNumbers method to 8. So it should return 8.But instead , it is returning 0.
Can anyone explain me what am I doing wrong.
EDIT : In reality , the values of a and b in Class1 are dynamic . In the sample code I have hardcoded it. And also , I do not want to test AddNumbers method. I want it to return some fixed value no matter what. In this case, i want it to return 8.
You specify the call to AddNumbers in your mock expectation with explicit numbers. Only when these explicit values are given to AddNumbers will 8 be returned. If you do not care about the actual parameters to AddNumbers you need to specify your expectation in a way that the parameters are ignored (e.g. via It.IsAny<>)
mockService.Setup(x => x.AddNumbers(It.IsAny<int>(),It.IsAny<int>())).Returns(c);
Also see https://github.com/Moq/moq4/wiki/Quickstart section "Matching Arguments".
Because in Class1 variables a and b differ from variables defined in getDataTest. Use the same values:
[TestMethod()]
public void getDataTest()
{
int a = 5, b = 9; // here
int c = 14; // and here
var mockService = new Mock<Interface1>();
mockService.Setup(x => x.AddNumbers(a,b)).Returns(c);
Class1 obj = new Class1(mockService.Object);
var result = obj.getData();
int final = result;
}
I am trying mock internal method in the same class.But my mocking fails.
Here is my code.
Interface
public interface IStudentService
{
int GetRank(int studentId);
IList<Subject> GetSubjects(int studentId);
}
Implementation
public class StudentService : IStudentService
{
private readonly IStudentRepository _studentRepository;
private readonly ISubjectRepository _subjectRepository;
public StudentService(IStudentRepository studentRepository, ISubjectRepository subjectRepository)
{
_studentRepository = studentRepository;
_subjectRepository = subjectRepository;
}
public int GetRank(int studentId)
{
IList<Subject> subjects = GetSubjects(studentId);
int rank = 0;
//
//Calculate Rank
//
return rank;
}
public virtual IList<Subject> GetSubjects(int studentId)
{
return _subjectRepository.GetAll(studentId);
}
}
Unit Test
[TestFixture]
public class StudentServiceTest
{
[SetUp]
public void Setup()
{
}
[TearDown]
public void TearDown()
{
}
[Test]
public void GetRankTest()
{
using (var mock = AutoMock.GetStrict())
{
var mockStudentService = new Mock<IStudentService>();
mockStudentService.Setup(x => x.GetSubjects(1)).Returns(new ServiceResponse<SystemUser>(new List<Subject>{ new AccounProfile(), new AccounProfile()}));
mock.Provide(mockStudentService.Object);
var component = mock.Create<StudentService>();
int rank = component.GetRank(1);
mockStudentService.VerifyAll();
Assert.AreEqual(1, rank, "GetRank method fails");
}
}
}
When I debug the code it is not mocking the GetSubjects method. It actually go inside to that method. I am using Nunit, Moq and Autofac to write unit test.
Thanks In Advance!
There are two solutions.
1. Partial mocking
In this approach you create mock of component you're testing (StudentService) and tell Moq to mock some of its methods (GetSubjects -- to-be-mocked methods must be virtual), while delegating others (GetRank) to base implementation:
Setting mock.CallBase = true instructs Moq to delegate any call not matched by explicit Setup call to its base implementation.
// mockStudentService is not needed, we use partial mock
var service = mock.Create<StudentService>();
service.CallBase = true;
service.Setup(m => m.GetSubjects(1)).Returns(...);
var rank = service.GetRank(1);
// you don't need .VerifyAll call, you didn't not set any expectations on mock
Assert.AreEqual(1, rank, "GetRank method fails");
2. Mocking internal service (ISubjectRepository)
Partial mocks are reserved for special cases. Your case is rather common one. Instead of mocking itself, your component (StudentService) could rely on mocked ISubjectRepository to provide subjects for it:
using (var mock = AutoMock.GetStrict())
{
var subjectRepositoryMock = new Mock<ISubjectRepository>();
subjectRepositoryMock.Setup(x => x.GetSubjects(1)).Returns(...);
mock.Provide(subjectRepositoryMock.Object);
var component = mock.Create<StudentService>();
int rank = component.GetRank(1);
// verify is not needed once again
Assert.AreEqual(1, rank, "GetRank method fails");
}
This code works for. Thank you for everyone for support
[TestFixture]
public class StudentServiceTest
{
private Mock<StudentRepository> _studentRepositoryMock;
private Mock<SubjectRepository> _subjectRepositoryMock;
private Mock<StudentService> _studentServiceMock;
[SetUp]
public void Setup()
{
_studentRepositoryMock = new Mock<StudentService>(MockBehavior.Strict);
_subjectRepositoryMock = new Mock<SubjectRepository>(MockBehavior.Strict);
_studentServiceMock = new Mock<StudentService>(_studentRepositoryMock.Object, _subjectRepositoryMock.Object);
_studentServiceMock.CallBase = true;
}
[TearDown]
public void TearDown()
{
}
[Test]
public void GetRankTest()
{
_studentServiceMock.Setup(x => x.GetSubjects(1)).Returns(...);
int rank = component.GetRank(1);
_studentServiceMock.VerifyAll();
Assert.AreEqual(1, rank, "GetRank method fails");
}
}
I guess your GetSubjects method must be declared virtual, otherwise it cannot be mocked.
public virtual IList<Subject> GetSubjects(int studentId)
{
// code here
}
I have the following test, with supporting classes, but I can't figure out how to verify the call on the dependency.
[TestFixture]
public class AnonymousGenericTypeParameterTests
{
[Test]
public void Test()
{
// Arrange
var dependency = new Mock<IDependency>();
var towns = new List<Town>
{
new Town { Name = "Lifford", County = "Donegal", Country="Ireland", Population = 1658 },
new Town { Name = "Ballyshannon", County = "Donegal", Country="Ireland", Population = 2504 },
new Town { Name = "Buxton", County = "Derbyshire", Country="United Kingdom", Population = 13599 },
};
var sut = new MyClass(dependency.Object);
// Act
sut.DoSomething(towns);
// Assert
// The following line needs to be fixed.
dependency.Verify(d => d.Execute(It.IsAny<IEnumerable<object>>(), It.IsAny<Func<object, decimal?>>()));
}
}
public interface IDependency
{
void Execute<T>(IEnumerable<T> collection, Func<T, decimal?> rateSelector);
}
public class MyClass
{
private readonly IDependency dependency;
public MyClass(IDependency dependency)
{
this.dependency = dependency;
}
public void DoSomething(IEnumerable<Town> towns)
{
var counties = towns.GroupBy(t => new {t.Country,t.County});
foreach (var county in counties)
{
dependency.Execute(county, c => c.Population);
}
}
}
public class Town
{
public string Name { get; set; }
public string County { get; set; }
public int Population { get; set; }
public string Country { get; set; }
}
According to Moq's test output, the performed invocations are:
Dependency.Execute(System.Linq.Lookup`2+Grouping[<>f__AnonymousType0`2[System.String,System.String],UniFocus.Staffscope4.Tests.Town], System.Func`2[UniFocus.Staffscope4.Tests.Town,System.Nullable`1[System.Decimal]])
I see plenty of questions regarding anonymous parameters in Moq (such as this and this and this), but can't find anything relating to using an anonymous type as the actual type parameter.
What can be put in the Verify line so that it actually verifies the call inside?
Note: My example IDependency doesn't return a value (it's already complex enough, I think), but there will be bonus kudos for answers that implictly or explicitly address Setup() as well as Verify().
Update
Jesse's solution only passes the test because I made a bad choice when crafting my example. I should have realised that any IGrouping<out TKey, out TElement> is also an IEnumerable<TElement>. Is there a more universal solution?
Update 2
I feel like my original example was possibly too elaborate and didn't represent well the actual title of my question. Is there any solution that works for this more straightforward and to-the-point example?
using Moq;
using NUnit.Framework;
namespace Tests
{
[TestFixture]
public class SimpleAnonymousGenericTypeParameterTests
{
[Test]
public void Test()
{
// Arrange
var dependency = new Mock<IDependency>();
var sut = new MyClass(dependency.Object);
// Act
sut.DoSomething("Donegal", "Lifford");
// Assert
// This verify works for both calls to Execute()
dependency.Verify(d => d.Execute(It.IsAny<object>()), Times.Exactly(2));
// This verify should specifically refer to only the first call to Execute()
dependency.Verify(d => d.Execute(It.IsAny</*HowToRepresentAnonymousTypeHere*/object>()), Times.Once);
}
public interface IDependency
{
void Execute<T>(T thing);
}
public class MyClass
{
private readonly IDependency dependency;
public MyClass(IDependency dependency)
{
this.dependency = dependency;
}
public void DoSomething(string county, string town)
{
dependency.Execute(new { county, town });
object someUnknownObject = "";
dependency.Execute(someUnknownObject);
}
}
}
}
The accepted answer doesn't work for me, I believe it's because the tests and the object in question are in a different assembly so Moq doesn't know how to reconcile the types and does not match them.
Instead, I created the following helper methods that can verify that the anonymous type provided has the correct fields and values:
public static class AnonHelpers
{
public static object MatchAnonymousType(object expected)
{
return Match.Create(Matcher(expected));
}
private static Predicate<object> Matcher(object expected)
{
return actual =>
{
var expectedProp = expected.GetType().GetProperties().ToDictionary(x => x.Name, x => x.GetValue(expected));
var actualProp = actual.GetType().GetProperties().ToDictionary(x => x.Name, x => x.GetValue(actual));
foreach (var prop in expectedProp)
{
if (!actualProp.ContainsKey(prop.Key))
return false;
if (!prop.Value.Equals(actualProp[prop.Key]))
return false;
}
return true;
};
}
}
They can be used like so:
var anon = new { SomeKey = "some value", SomeOtherKey = 123 };
myMock.Setup(x => x.MyMethod(personIDs, AnonHelpers.MatchAnonymousType(anon))).Verifiable();
This will create a matcher that will use reflection to match the anonymous type based on it's keys and values and then you can use normal verification to see when it's been called.
Since the types are known in the context of the test, you could provide the specific type arguments to the Verify call. The following change got the test to pass:
dependency.Verify(d =>
d.Execute(It.IsAny<IEnumerable<Town>>(), It.IsAny<Func<Town, decimal?>>()));
The same should also work for setups.
With regards to the example in Update 2, the following passes, but it requires knowledge of the inner workings of the DoSomething() method and as far as I know it's the only way to make it work:
var anonymousType = new {county = "Donegal", town = "Lifford"};
dependency.Verify(d => d.Execute(anonymousType), Times.Once);
I've have searched on this and it seems to be a catch all, unfortunately everything I've read doesn't help figure it out. Here is the class:
public interface IMockInterface
{
MockClass MockedMethod();
MockClass MockThis();
}
public class MockClass : IMockInterface
{
public virtual MockClass MockedMethod()
{
MockClass returnValue;
returnValue = new MockClass();
returnValue.SomeMessage = "Not mocked";
return returnValue;
}
public MockClass MockThis()
{
MockClass mock;
MockClass returnValue;
mock = new MockClass();
return mock.MockedMethod();
}
}
And the test:
public void MockTest_Internal()
{
MockClass mainClass;
MockClass returnedClass;
IMockInterface mockProvider;
mainClass = new MockClass();
mockProvider = repository.StrictMock<IMockInterface>();
Expect.Call(mockProvider.MockedMethod())
.Return(new MockClass { SomeMessage = "Mocked" });
repository.ReplayAll();
returnedClass = mainClass.MockThis();
provider.AssertWasCalled(item => item.MockedMethod());
Assert.IsTrue(returnedClass.SomeMessage == "Mocked");
}
And have also tried and doesn't work
But I keep getting this exception:
Rhino.Mocks.Exceptions.ExpectationViolationException:
IMockInterface.MockedMethod(); Expected #1, Actual #0
Now from what I've read this would suggest either the method was called with different than expected parameters OR the method was never called but was expected to be called. This isn't the case for the test.
Side Note: This is my first time really using Rhino.Mocks without some in house code so I am basically picking it up as I go. There could be something really stupid here...
This was the old test commented on, but is not what I should have been using:
public void MockTest_Internal()
{
MockClass mainClass;
MockClass returnedClass;
IMockInterface mockProvider;
mainClass = new MockClass();
var provider = MockRepository.GenerateStub<IMockInterface>();
provider.Stub(item => item.MockedMethod())
.Return(new MockClass { SomeMessage = "Mocked" });
returnedClass = mainClass.MockThis();
provider.AssertWasCalled(item => item.MockedMethod());
Assert.IsTrue(returnedClass.SomeMessage == "Mocked");
}
You're telling the mock framework to stub the MockedMethod class on the provider object, but you never inject the provider into the mainClass object to be used. It's not clear to me what you are trying to accomplish but if you want the mocked method to be called then it has to be called on the object on which the stub was set up.
If you define MockThis as below, I think you will find that it will work.
public MockClass MockThis(IMockInterface provider)
{
return provider.MockMethod();
}
The bottom line is that you get the exception because the method was never called on the provider, only on the mainClass object.
EDIT: Example
public class ClassUnderTest
{
private ProviderClass provider { get; set; }
public ClassUnderTest( ProviderClass provider )
{
this.Provider = provider;
}
public int DoOperation()
{
return this.Provider.ProviderOperation();
}
}
public class ProviderClass
{
private int value = 42;
public ProviderClass()
{
}
public virtual int ProviderOperation()
{
return this.value;
}
}
[TestMethod]
public void DoOperationTest()
{
ProviderClass mockProvider = MockRepository.GenerateMock<ProviderClass>();
mockProvider.Expect( mp => mp.ProviderOperation() ).Return( -1 );
ClassUnderTest target = new ClassUnderTest( mockProvider );
int expectedValue = -1;
int value = target.DoOperation();
Assert.AreEqual( expectedValue, value );
mockProvider.VerifyAllExpectations();
}
Normally the ProviderClass object would return 42 from the ProviderOperation method, but we've mocked it out and told it to return -1. When the ClassUnderTest DoOperation method is called, the mock provider object's ProviderOperation method is invoked and returns the mocked value of -1.
Hope this helps.
I usually get this error when a stubbed method is called with an object argument that I build in the test and in the tested code the object is built before calling that method. The solution is to use the Rhino.Mocks Matches().
Ex:
Arg<string>.Matches(s => s.Contains("some substring"))