Testing a specific implementation with Moq - c#

Update 1, more details
My question was hard to interpret, sorry for that....
Simple question...
How do you test a specific implementation with Moq?
interface IShipping
{
int CalculateCost();
}
class TruckShipping: IShipping
{
int CalculateCost()
{
return 9;
}
}
class Shipping: IShipping
{
int CalculateCost()
{
return 5;
}
}
class CalculateSomethingMore
{
IShipping _shipping;
CalculateSomethingMore(IShipping shipping)
{
// Here I want the TruckShipping implementation!
_shipping = shipping;
}
DoCalc()
{
return _shipping.CalculateCost * 2;
}
}
Without mock it would probably look like (if you don't use DI)
TEST:
var truckShipping = new TruckShipping();
var advancedCalculation = CalculateSomethingMore(truckShipping);
var result = DoCalc();
var expected = 18;
Assert.IsTrue(result == expected);
NUnit, FluentAssertions, MbUnit, xUnit, etc.. doesn't matter :)
Test:
var truckShipping = Mock.Of<IShipping> .... ? I want to test the TruckShipping implementation.
and inject that into CalculateSomethingMore.

If you want to test TruckShipping implementation then you need separate tests for TruckShipping implementation.
Currently you are testing behavior of CalculateSomethingMore, which should return doubled value of cost, calculated by shipping. You don't care which shipping. Responsibility of CalculateSomethingMore is asking shipping about it's cost, and doubling that cost:
Mock<IShipping> shipping = new Mock<IShipping>();
shipping.Setup(s => s.CalculateCost()).Returns(10);
CalculateSomethingMore sut = new CalculateSomethingMore(shipping.Object);
Assert.That(20, Is.EqualTo(sut.DoCalc()));
shipping.VerifyAll();
You can see, that this test uses neither 9 nor 5 as shipping cost. Why? Because you actually don't care what value it will have. Calculating shipping cost is not responsibility of class under test.
Also you need another test for your TruckShipping implementation, which will verify, that TruckShipping calculates shipping cost correctly (this is a responsibility of your shipping object):
TruckShipping sut = new TruckShipping();
Assert.That(9, Is.EqualTo(sut.DoCalc());

Moq is not a testing framework, it's a mockinq framework, so it does not provide testing features.
For testing you can use SharpTestEx, for example you can write:
[TestMethod]
public void VerifyCostIsCorrect()
{
new TruckShipping()
.CalculateCost()
.Should("The TruckShipping implementation returns a wrong cost.").Be.EqualTo(9);
}

You use mocks to replace real dependencies (which often are too complex to instantiate) with faked, lightweight objects. Testing mocked object makes no sense at all because essentially, you'll be testing auto-generated code from some 3rd party library.
Edit:
It's still unclear why would you want to depend on concrete implementation, especially considering you're using IoC and inject IShipping. Anyways, I think you want something that can simulate TruckShipping, but not TruckShipping itself. If so, it's simple:
var shippingMock = new Mock<IShipping>();
// setting up mock to return 9 makes it behave as if it was TruckShipping
shippingMock.Stub(s => s.CalculateCost()).Returns(9);
var advancedCalculation = CalculateSomethingMore(shippingMock.Object);
var result = DoCalc();
var expected = 18;
Assert.IsTrue(result == expected);

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!

Create multiple instances of the same type with different behaviour in Moq (with Autofac)

I'm trying to write a unit test over an class that has 4 instances of the same object (object is an interface to hardware, the class is a manager of a configuration of hardware). I've used Autofac, so I'm using the Autofac.Extras.Moq library.
I need to have multiple instances of mocks, with different behaviour (basically I'm trying to test behaviour when a device fails by setting a property. I'm trying hard but I can see how to configure a mock to do what I want, but when I change the behaviour, it's changing all instances of that mock, not just the mocks.
using(mock = AutoMock.GetLoose())
{
var goodHW = mock.Create<IHW>();
((Mock<IHW>)goodHW).Setup(x => x.OK).Returns(true);
var badHW = mock.Create<IHW>();
((Mock<IHW>)badHW).Setup(x => x.OK).Returns(false);
mock.Mock<IHWManager>().SetupGet(x => x.HW1).Returns(goodHW);
mock.Mock<IHWManager>().SetupGet(x => x.HW2).Returns(badHW);
Assert.AreNotEqual(goodHW, badHW) //FAILS!!!
}
As the two mocks are actually the same object, the goodHW instance returns false. I can use a sequence, but that ties the test logic to the implementation logic significantly (order of calls etc.)
Is what I'm asking possible?
You could try creating two mock objects (call GetLoose()twice) and set them up differently; then use one to create goodHW and the other to create badHW
Something like this:
using(mockGood = AutoMock.GetLoose())
using(mockBad = AutoMock.GetLoose())
{
var goodHW = mockGood.Create<IHW>();
((Mock<IHW>)goodHW).Setup(x => x.OK).Returns(true);
var badHW = mockBad.Create<IHW>();
((Mock<IHW>)badHW).Setup(x => x.OK).Returns(false);
mockGood.Mock<IHWManager>().SetupGet(x => x.HW1).Returns(goodHW);
mockBad.Mock<IHWManager>().SetupGet(x => x.HW2).Returns(badHW);
Assert.AreNotEqual(goodHW, badHW) // SUCCESS??
}

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...

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);

What is the AAA syntax equivalent to using Ordered() in Rhino Mocks

I can't for the life of me find the proper syntax using the Fluent/AAA syntax in Rhino for validating order of operations.
I know how to do this with the old school record/playback syntax:
MockRepository repository = new MockRepository();
using (repository.Ordered())
{
// set some ordered expectations
}
using (repository.Playback())
{
// test
}
Can anyone tell me what the equivalent to this in AAA syntax for Rhino Mocks would be. Even better if you can point me to some documentation for this.
Try this:
//
// Arrange
//
var mockFoo = MockRepository.GenerateMock<Foo>();
mockFoo.GetRepository().Ordered();
// or mockFoo.GetMockRepository().Ordered() in later versions
var expected = ...;
var classToTest = new ClassToTest( mockFoo );
//
// Act
//
var actual = classToTest.BarMethod();
//
// Assert
//
Assert.AreEqual( expected, actual );
mockFoo.VerifyAllExpectations();
Here's an example with interaction testing which is what you usually want to use ordered expectations for:
// Arrange
var mockFoo = MockRepository.GenerateMock< Foo >();
using( mockFoo.GetRepository().Ordered() )
{
mockFoo.Expect( x => x.SomeMethod() );
mockFoo.Expect( x => x.SomeOtherMethod() );
}
mockFoo.Replay(); //this is a necessary leftover from the old days...
// Act
classToTest.BarMethod
//Assert
mockFoo.VerifyAllExpectations();
This syntax is very much Expect/Verify but as far as I know it's the only way to do it right now, and it does take advantage of some of the nice features introduced with 3.5.
The GenerateMock static helper along with Ordered() did not work as expected for me. This is what did the trick for me (the key seems to be to explicitly create your own MockRepository instance):
[Test]
public void Test_ExpectCallsInOrder()
{
var mockCreator = new MockRepository();
_mockChef = mockCreator.DynamicMock<Chef>();
_mockInventory = mockCreator.DynamicMock<Inventory>();
mockCreator.ReplayAll();
_bakery = new Bakery(_mockChef, _mockInventory);
using (mockCreator.Ordered())
{
_mockInventory.Expect(inv => inv.IsEmpty).Return(false);
_mockChef.Expect(chef => chef.Bake(CakeFlavors.Pineapple, false));
}
_bakery.PleaseDonate(OrderForOnePineappleCakeNoIcing);
_mockChef.VerifyAllExpectations();
_mockInventory.VerifyAllExpectations();
}
tvanfosson's solution does not work for me either. I needed to verify that calls are made in particular order for 2 mocks.
According to Ayende's reply in Google Groups Ordered() does not work in AAA syntax.

Categories