Other than mocked method call actual methods for a mock object - c#

IFoo
{
string abc();
string def();
}
Foo: IFoo
{
string abc()
{
def();
}
string def()
{
}
}
Mymainclass
{
private IFoo _foo;
public Mymainclass():this(new Foo())
{}
public Mymainclass(IFoo foo)
{
_foo = foo;
}
string mainmethod()
{
_foo.abc();
}
}
[TestClass]
public class Mymainclasstester
{
Mymainclass mainclass;
Mock<IFoo> mifoo;
[TestInitialize]
public void TestInitialize()
{
mifoo = new Mock<IFoo>();
mifoo.Setup(x => x.def(It.IsAny<string>())).Returns("abc");
mainclass = new Mymainclass(mifoo.Object);
}
[TestMethod]
public void testmethod()
{
mainclass.mainmethod();
}
}
As seen above in the testmethod() i am calling mainmethod() of class Mymainclass, which inturn calls abc() of Foo class.
abc() makes call to def() as it can be seen in the above code. I have mocked only def().
When the call is made from testmethod() i want to make an actual call to abc() of Foo, and mock only def().
Currently with this implementation abc() is not executing.
Can anyone help me on this?

You cannot archive what you want using interface. Actually, you can but by mocking abc to invoke def which seems a bit awkward:
mock.Setup(x => x.abc()).Returns(() => mock.Object.def());
Although I don't see the point here, you could just mock abc instead...
The only way to archive what you want using mock is by using actual class and Callbase feature.
public class Foo : IFoo
{
public virtual string abc() //methods have to be virtual to be mockable
{
return def();
}
public virtual string def() //methods have to be virtual to be mockable
{
return "123";
}
}
//setup
var mock = new Mock<Foo>();
mock.Setup(x => x.def()).Returns("abc");
mock.Setup(x => x.abc()).CallBase();
mock.Object.abc(); // "abc"
In this case, you are setting up the actual class instead of the interface so you need to refactor a bit your implementation. Not sure if this is the right approach just the way how to implement your requirement.

Related

Mock a method of class under test with Moq & AutoMock

I've been reading around and I can't seem to find a case that matches the behavior I want with Moq.
I want to mock a specific method (which is interfacing with an external API) of a class that I want to test. The problem is that, as I understand it, once the class is .Create<T>, you cannot .Setup()... any method on it.
Here is an example:
public class ClassA
{
public void ConfigureExpansion()
{
var classB = new ClassB();
var data = GetExternalData(); // I want to mock this
//data is used in the code
classB.TaskB(data); // I want to mock this
}
public string GetExternalData()
{
return data...
}
}
public class ClassB
{
public void TaskB(String myData)
{
//Does some work
}
}
[TestMethod]
public void Test()
{
using (var mock = AutoMock.GetLoose())
{
mock.Mock<IClassB>().Setup(x => x.TaskB(It.IsAny<string>()));
var cls = mock.Create<ClassA>();
cls.Setup(x => x.GetExternalData(It.IsAny<string>())).Return("MyData"); // <--- This is not valid, but represents what I am trying to do.
//act
cls.ConfigureExpansion();
mock.Mock<IClassB>().Verify(x => x.TaskB(), Times.Once);
}
}
I tried to set up a mock for the interface of my class under test, but the cls won't call it:
[TestMethod]
public void Test()
{
using (var mock = AutoMock.GetLoose())
{
mock.Mock<IClassA>().Setup(x => x.GetExternalData(It.IsAny<string>())).Return("MyData"); //<--- Mocking the method here is not detected by the cls below
mock.Mock<IClassB>().Setup(x => x.TaskB(It.IsAny<string>()));
var cls = mock.Create<ClassA>();
//act
cls.ConfigureExpansion();
mock.Mock<IClassB>().Verify(x => x.TaskB(), Times.Once);
}
}
I've also tried instantiating my class-under-test and when I do it like this, it doesn't take the mocks (ClassB) into consideration:
[TestMethod]
public void Test()
{
using (var mock = AutoMock.GetLoose())
{
mock.Mock<IClassA>().Setup(x => x.GetExternalData(It.IsAny<string>())).Return("MyData"); //<--- Mocking the method here is not detected by the cls below
mock.Mock<IClassB>().Setup(x => x.TaskB(It.IsAny<string>()));
var cls = new ClassA();
//act
cls.ConfigureExpansion();
mock.Mock<IClassB>().Verify(x => x.TaskB(), Times.Once);
}
}
I would really appreciate any insights about this,
Thank you
Here is one approach for your problem. If you want to test ConfigureExpansion of ClassA, you have to mock the dependencies used in that method, which is ClassB. You cannot mock GetExternalData of ClassA because ClassA is the class under test now. You may have to refactor your classes in a way so that there is a ClassUnderTest which creates both instances of ClassA and ClassB using dependency injection. Then, you can use Moq to mock the interfaces IClassA and IClassB to test the ConfigureExpansion.
public class ClassUnderTest
{
private readonly IClassA _classA;
private readonly IClassB _classB;
public ClassUnderTest(IClassA classA, IClassB classB)
{
this._classA = classA;
this._classB = classB;
}
public void ConfigureExpansion()
{
var data = this._classA.GetExternalData();
this._classB.TaskB(data);
}
}
public interface IClassA
{
string GetExternalData();
}
public class ClassA : IClassA
{
public string GetExternalData()
{
return "some data";
}
}
public interface IClassB
{
void TaskB(string myData);
}
public class ClassB : IClassB
{
public void TaskB(string myData)
{
//Does some work
}
}
The test method can be:
[TestMethod]
public void Test()
{
using (var mock = AutoMock.GetLoose())
{
var mockClassA = mock.Mock<IClassA>();
var mockClassB = mock.Mock<IClassB>();
mockClassA.Setup(x => x.GetExternalData()).Returns("MyData");
var cls = new ClassUnderTest(mockClassA.Object, mockClassB.Object);
//act
cls.ConfigureExpansion();
mockClassB.Verify(x => x.TaskB(It.IsAny<string>()), Times.Once);
}
}

Mock certain part of the method using Moq

I'm new to Moq and I would like to mock certain part of my method to test the business logic but having problem to mock the GetCountry method. Below is the code that I used as sample.
public class Class1
{
public void Process()
{
MyClass foo = new MyClass();
var o = foo.GetCountry(); //I would like to mock this part.
//Business Logic here
}
}
public class MyClass : IFoo
{
public List<string> GetCountry()
{
//Get the data from Database.. someone will do this
throw new NotImplementedException();
}
}
Below is my Test Code that I used.
[TestMethod]
public void TestMethod2()
{
var mock = new Moq.Mock<IFoo>();
mock.Setup(m => m.GetCountry()).Returns(new List<string> { "America", "Philippines", "Japan" });
ClassLibrary1.Class1 foo = new ClassLibrary1.Class1();
//still called the not implemented exception
foo.Process();
}
Your code currently doesn't have an easy way to replace one implementation to another. Try this approach:
public class Class1
{
// Instead of using a concrete class, use an interface
// also, promote it to field
IFoo _foo;
// Create a constructor that accepts the interface
public Class1(IFoo foo)
{
_foo = foo;
}
// alternatively use constructor which provides a default implementation
public Class1() : this(new MyClass())
{
}
public void Process()
{
// Don't initialize foo variable here
var o = _foo.GetCountry();
//Business Logic here
}
}
If you have such setup it is quite easy to mock it using your code:
[TestMethod]
public void TestMethod2()
{
var mock = new Moq.Mock<IFoo>();
mock.Setup(m => m.GetCountry()).Returns(new List<string> { "America", "Philippines", "Japan" });
// Pass mocked object to your constructor:
ClassLibrary1.Class1 foo = new ClassLibrary1.Class1(mock.Object);
foo.Process();
}

Moq an object created inside the method being tested

In the following example, I want to test the TestMe.DoSomething() function.
I want to mock the ISomething interface that is used within this method and make it return different values (depending on the specific unit test.)
In real life the ISomething interface winds up calling out to expensive 3rd party resources -- I definitely don't want to just call a real ISomething.
Here is the example structure:
class TestMe
{
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
private ISomething SomethingFactory()
{
return new Something();
}
}
interface ISomething
{
int Run();
}
class Something : ISomething
{
public int Run()
{
return 1;
}
}
Here is code that doesn't work:
var fakeSomething = new Mock<ISomething>();
var testMe = new TestMe();
Mock.Get(testMe).Setup(p => p.SomethingFactory()).Returns(fakeSomething.Object);
testMe.DoSomething();
Because SomethingFactory() is private, I cannot set the return value from that method to be what I want.
Any advice on how I can solve this?
Make the factory a full interface / class and remove the SomethingFactory method from TestMe.
public interface ISomethingFactory {
ISomething MakeSomething();
}
public sealed class SomethingFactory {
public ISomething MakeSomething() {
return new Something();
}
}
class TestMe
{
private readonly ISomethingFactory _somethingFactory;
public TestMe(ISomethingFactory somethingFactory) {
_somethingFactory = somethingFactory;
}
public void DoSomething()
{
ISomething s = _somethingFactory.MakeSomething();
int i = s.Run();
//do things with i that I want to test
}
}
This will allow you to mock ISomethingFactory to return a mock of ISomething.
While I think you may protest this solution as too drastic a change, I think its better than making a class that's not sealed with a members who's only reason for being virtual is for testing.
You can inject your dependency. If you don't want to break all your callers you can add two constructors and use the one that lets you inject fake in tests
class TestMe
{
private readonly ISomething something;
TestMe() : this(new RealSomething()
{
}
TestMe(ISomething sth)
{
something = sth;
}
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
private ISomething SomethingFactory()
{
return new Something();
}
}
Second way would be to change the
SomethingFactory
method to protected virtual and override it in derived class and use that class instead, or to setup
class TestableTestMe : TestMe
{
private readonly ISomething something;
TestableTestMe(ISomething testSpecific)
{
something = testSpecific;
}
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
protected override ISomething SomethingFactory()
{
return something;
}
}
This technique is called "extract and override"
Changing SomethingFactory() to be protected virtual allows you to use Moq.Protected to access the method by its name:
public class TestMe
{
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
protected virtual ISomething SomethingFactory()
{
return new Something();
}
}
public interface ISomething
{
int Run();
}
public class Something : ISomething
{
public int Run()
{
return 1;
}
}
So you can run this test:
var fakeSomething = new Mock<ISomething>();
fakeSomething.Setup(p => p.Run()).Returns(2);
var testMe = new Mock<TestMe>();
testMe.Protected().Setup<ISomething>("SomethingFactory").Returns(fakeSomething.Object);
testMe.Object.DoSomething();

Moq - Checking method call on concrete class

Here is a very simplistic example of what I'm trying to do:
public class Bar
{
public void SomeMethod(string param)
{
//whatever
}
}
public interface IBarRepository
{
List<Bar> GetBarsFromStore();
}
public class FooService
{
private readonly IBarRepository _barRepository;
public FooService(IBarRepository barRepository)
{
_barRepository = barRepository;
}
public List<Bar> GetBars()
{
var bars = _barRepository.GetBarsFromStore();
foreach (var bar in bars)
{
bar.SomeMethod("someValue");
}
return bars;
}
}
In my test, I'm mocking IBarRepository to return a concrete List defined in the unit test and passing that mocked repository instance to the FooService constructor.
I want to verify in the FooService method GetBars that SomeMethod was called for each of the Bars returned from the repository. I'm using Moq. Is there any way to do this without mocking the list of Bars returned (if even possible) and not having to put some hacky flag in Bar (yuck) ?.
I'm following an example from a DDD book, but I'm starting to think it smells because I'm challenged in testing the implementation....
Revised... this passes:
public class Bar
{
public virtual void SomeMethod(string param)
{
//whatever
}
}
public interface IBarRepository
{
List<Bar> GetBarsFromStore();
}
public class FooService
{
private readonly IBarRepository _barRepository;
public FooService(IBarRepository barRepository)
{
_barRepository = barRepository;
}
public List<Bar> GetBars()
{
var bars = _barRepository.GetBarsFromStore();
foreach (var bar in bars)
{
bar.SomeMethod("someValue");
}
return bars;
}
}
[TestMethod]
public void Verify_All_Bars_Called()
{
var myBarStub = new Mock<Bar>();
var mySecondBarStub = new Mock<Bar>();
var myBarList = new List<Bar>() { myBarStub.Object, mySecondBarStub.Object };
var myStub = new Mock<IBarRepository>();
myStub.Setup(repos => repos.GetBarsFromStore()).Returns(myBarList);
var myService = new FooService(myStub.Object);
myService.GetBars();
myBarStub.Verify(bar => bar.SomeMethod(It.IsAny<string>()), Times.Once());
mySecondBarStub.Verify(bar => bar.SomeMethod(It.IsAny<string>()), Times.Once());
}
Note the slight change to class Bar (SomeMethod() is virtual). A change, but not one involving a flag... :)
Now, in terms of broader design, there is some mutation going on with your bar (whatever "SomeMethod()" actually does). The best thing to do would probably be to verify that this mutation happened on each Bar returned from FooService.GetBars(). That is, setup your repository stub to return some bars, and then verify that whatever mutation is performed by SomeMethod() has taken place. After all, you control the Bars that will be returned, so you can setup their pre-SomeMethod() state, and then inspect their post-SomeMethod() state.
If I was writing these classes with unit testing in mind, I would likely either have the class Bar implement an interface IBar and use that interface in my service, or make SomeMethod virtual in Bar.
Ideally like this:
public interface IBar
{
void SomeMethod(string param);
}
public class Bar : IBar
{
public void SomeMethod(string param) {}
}
public interface IBarRepository
{
List<IBar> GetBarsFromStore();
}
public class FooService
{
private readonly IBarRepository _barRepository;
public FooService(IBarRepository barRepository)
{
_barRepository = barRepository;
}
public List<IBar> GetBars()
{
var bars = _barRepository.GetBarsFromStore();
foreach (var bar in bars)
{
bar.SomeMethod("someValue");
}
return bars;
}
}
Then my unit test would look as follows:
[Test]
public void TestSomeMethodCalledForEachBar()
{
// Setup
var barMocks = new Mock<IBar>[] { new Mock<IBar>(), new Mock<IBar>() };
var barObjects = barMocks.Select(m => m.Object);
var repoList = new List<IBar>(barsObjects);
var repositoryMock = new Mock<IBarRepository>();
repositoryMock.Setup(r => r.GetBarsFromStore()).Returns(repoList);
// Execute
var service = new FooService(repositoryMock.Object);
service.GetBars();
// Assert
foreach(var barMock in barMocks)
barMock.Verify(b => b.SomeMethod("someValue"));
}

Rhino mocks stub vs expect, always choosing first one why?

I went with this solution:
Stubbing a property twice with rhino mocks
but even when I change both of my Stubs to .Expect, the first Expect is winning out:
Here's the recreation in mono:
using System;
using NUnit.Framework;
using Rhino.Mocks;
namespace FirstMonoClassLibrary
{
[TestFixture]
public class TestingRhinoMocks
{
Sut _systemUnderTest;
IFoo _dependency;
[SetUp]
public void Setup()
{
_dependency = MockRepository.GenerateMock<IFoo>();
_dependency.Expect(x => x.GetValue()).Return(1);
_systemUnderTest = new Sut(_dependency);
}
[Test]
public void Test()
{
_dependency.Stub(x => x.GetValue()).Return(2);
var value = _systemUnderTest.GetValueFromDependency();
Assert.AreEqual(2, value); // Fails says it's 1
}
}
public interface IFoo
{
int GetValue();
}
public class Sut
{
private readonly IFoo _foo;
public Sut(IFoo foo)
{
_foo = foo;
}
public int GetValueFromDependency()
{
return _foo.GetValue();
}
}
}
you need to do the following:
[Test]
public void Test()
{
_dependency.BackToRecord();
_dependency.Expect(_ => _.GetValue).Return(2);
_dependency.Replay();
var value = _systemUnderTest.GetValueFromDependency();
value.ShouldBe(2); // Fails says it's 1
}

Categories