TDD can force the creation of "fake" dependencies - c#

I'm using a boilerplate implementation of Model-View-Presenter in an ASP.NET WebForms application. My View has two events of consequence, one that signals that the user has filled out enough fields on the domain model to initiate a duplication check, and the other is a regular Save event. My pseudo code looks like this:
public class ItemNewPresenter : PresenterBase<IItemNewView>
{
public IItemService Service { get; private set; }
public IItemNewView View { get; private set; }
public ItemNewPresenter(IItemService service, IItemNewView view)
{
Service = service;
View = view;
View.OnSave += DoItemSave;
View.OnItemIsDuplicateCheck+= DoItemIsDuplicateCheck;
}
private void DoItemIsDuplicateCheck(object sender, CheckItemDuplicateEventArgs e)
{
CheckForItemDuplication(e.Item);
}
private void CheckForItemDuplication(Item item){
if (Service.IsDuplicateItem(item))
{
View.RedirectWithNotification(BuildItemUrl(item), "This item already exists");
}
}
private void DoItemSave(object sender, SaveItemEventArgs e)
{
DoItemIsDuplicateCheck(this, e.ToItemDuplicateEventArgs());
Service.Save(e.Item);
}
}
Here's my test for ensuring that my presenter behaves properly when OnItemIsDuplicateCheck is raised from the view:
[Test]
public void presenter_checking_for_existing_item_should_call_redirect_if_found()
{
var service = new Mock<IItemService>();
var view = new Mock<IItemNewView>();
var presenter = new ItemNewPresenter (service.Object, view.Object);
var onCheckExistingHandler = view.CreateEventHandler <CheckItemDuplicateEventArgs>();
view.Object.OnExistingDenominatorCheck += onCheckExistingHandler;
var eventArgs = new CheckItemDuplicateEventArgs();
service.Setup(s => s.IsDuplicate(It.Is<CheckItemDuplicateEventArgs>(c => c.Equals(eventArgs)))).Returns(true);
onCheckExistingHandler.Raise(eventArgs);
view.Verify(v => v.RedirectWithNotification(It.IsAny<String>(), It.IsAny<string>()), Times.Once());
service.Verify();
}
For consistency, I would like to have the same duplicate check fired when the View raises the OnSave event. My question is around how I am supposed to write my test when one of the methods I want to verify (CheckForItemDuplication) is declared on the class under test. The alternative to verifying the method invocation on the SUT (bad) would be to write my save test with lots of duplicated code (setup and assertion of all my mocks would be copied from the above test) and it also makes the unit test less focused.
[Test]
public void presenter_saving_item_should_check_for_dupe_and_save_if_not_one() {
//duplicate mocks/setups/asserts from duplicate check fixture
//additional mocks/setups/asserts to test save logic
}
I think TDD would suggest pulling this private method out into a separate class that collaborates with my Presenter and would be injected via DI. But adding another dependency to my Presenter for functionality that doesn't seem worthy of being a freestanding abstraction *and*represents an internal implementation detail of my Presenter seems...well...crazy. Am I way off base here? There must be some design pattern or refactoring I can apply that would avoid the need to turn a private method into a dependency.

What I have done sometimes, when confronted with this dilemma, is to extract the function, make an internal constructor with the object as argument, AND a public constructor without. The public ctor is forwarded to the internal with a new object such as:
public class ClassThatUseInjection
{
private readonly SomeClass _injectedClass;
public ClassThatUseInjection(): this(new SomeClass()) {}
internal ClassThatUseInjection(SomeClass injectedClass)
{
_injectedClass = injectedClass;
}
}
public class SomeClass
{
public object SomeProperty { get; set; }
}
Thus, you can use the empty constructor from outside, and the other constructor for when you want to inject a stubbed argument for testpurposes. As long as the empty constructor only forwards the call without any logic of its own, you can still test it, like it has only one constructor.

I would go with testing the class as is by adding the duplicate setup code. Once that test is passing and you are confident all test cases are covered you can then refactor your test code to remove duplication.
You can move the dependencies (service and view) to private fields, then add a method to create the SUT:
private Mock<IItemService> _service;
private Mock<IItemNewView> _view;
private PresenterBase<IItemNewView> CreateSUT()
{
_service = new Mock<IItemService>();
_view = new Mock<IItemNewView>();
return new ItemNewPresenter (service.Object, view.Object);
}
(I think most people would prefer to initialize the Mock objects in the Setup method.)
Call the CreateSUT from your tests and now there is a little less duplication. Then you may want to add private method(s) for creating the event handler / raising the event as long as it is something that is being done the same or similar in more than one tests case.
Having this CreateSUT method cuts down on the amount of test code that is calling your constructor making it easier in the future if you were to add / remove / change dependencies. If you treat your test code like any other code and use the DRY principle when you see duplication it can result in more explicit, easier to read, maintainable test code. Dealing with very similar setup and test context is a common issue with unit testing and should not always change how the class being tested is/was designed.

I'll be interested if there are better answers, as I encounter this all the time.
The alternative to verifying the method invocation on the SUT (bad) would be to write my save test with lots of duplicated code (setup and assertion of all my mocks would be copied from the above test) and it also makes the unit test less focused.
I'm not sure why you feel it makes the test less focused, but in your shoes I would do exactly what it sounds like you don't want to do--have duplicated setup code to test isolated cases for the SUT. You are testing the external behavior of the SUT with the test you supplied, which seems exactly right to me.
I am personally not a fan of exposing more than is necessary from a class and/or making behavior that should be the responsibility of the SUT into a dependency just to facilitate testing. The "natural boundry" of the class's responsibility should not be violated just because you want to test it.

It is easier to unit-test the calculation of the url than to unit-test that redirection has occured.
If i understood you corretly you want to test that the mvp-s CheckForItemDuplication() redirects to a certain url by raising
the view-mock-s OnItemIsDuplicateCheck event.
private void CheckForItemDuplication(Item item)
{
if (Service.IsDuplicateItem(item))
{
View.RedirectWithNotification(BuildItemUrl(item),
"This item already exists");
}
}
In my opinion you are doing to much.
What if you rewrite your code as
internal protected GetErrorUrlForItem(Item item)
{
if (Service.IsDuplicateItem(item))
{
return BuildItemUrl(item,
"This item already exists");
}
return null;
}
private void CheckForItemDuplication(Item item)
{
var result = GetErrorUrlForItem(item);
if (result != null)
{
View.RedirectWithNotification(result);
}
}
In the unittest just test the internal method GetErrorUrlForItem(). You have to use the InternalsVisibleTo attribute to allow accessing the internal method.

Related

Should I use a callback or introduce a public field to aid with unit testing?

I've seen adding public properties advocated in the Art of Unit Testing (by Roy Osherove) to help get at and setup awkward (or internal) collaborators/collaborations used by a SUT, and have used this technique myself to good effect. (Also I have seen a similar approach using an additional constructor instead)
Likewise, a testing isolation framework (such as Moq) can provide an alternative and using Moq a Callback can be used to help set up an awkward collaborator/collaboration.
The trade off's that I have experienced here are that:
Using a public field introduces additional items into the SUT, with slightly cleaner testing code
Versus
A SUT uncluttered by additional items to make it testable and slightly more clunky testing code (the callback code is not the prettiest).
In my situation and, owing to a constraint on what is a command AND should be a query - a query which could return stubbed data, there is no easy way to administer the collaboration in the SUT (without the aforementioned mechanisms)
A collaborator in the SUT updates an object passed by reference in a command, this looks lik: (repeated in code examples a little later)
var warehouse = new Warehouse(); // internal to Order
_repo.Load(warehouse); // Warehouse is filled by reference
EDIT: I have contrived an example which has design problems - Warehouse and Order are overly intimate, an application service could be use to orchastrate interactions etc. The Nub of the problem is that I have very little control over how the Warehouse gets populated. I am using a framework which uses a command to hydrate an object by reference. This IS the problem, I know, but unfortunately I am constrained by it. So the real focus of this question is not about a redesign but purely which method, callback or public field would be preferable, if this is all we had to work with.
The code examples below are both working examples using Moq and NUnit.
For the purposes of time I have omitted adding an application service to orchestrate the example use case ( which is basically fill an Order from a compliant Warehouse - based on Fowler's Mocks aren't Stubs example ). Also both approaches take a classic approach to unit testing, asserting state as opposed to verifying behaviour and this isn't my intended focus of the question.
Before going on, I do have a preference but I would be interested to see what other people suggest or prefer.
So firstly the public property approach, code and tests: (smarts in the use of the Func<>)
public class Order
{
private readonly IWarehouseRepo _repo;
public int Items { get; private set; }
public Func<Warehouse> WarehouseBuilder { get; set; }
public Order(IWarehouseRepo repo)
{
_repo = repo;
}
public void AddOrderItems(int numberOfItems)
{
var warehouse = WarehouseBuilder();
_repo.Load(warehouse);
warehouse.RemoveStock(numberOfItems);
Items += numberOfItems;
}
}
public class Warehouse
{
public int Items { get; set; }
public void RemoveStock(int numberOfItems)
{
Items -= numberOfItems;
}
}
[TestFixture]
public class Given_A_Warehouse_With_20_Items
{
private Order _order;
private Mock<IWarehouseRepo> _warehouseRepo;
private Warehouse _warehouse;
[SetUp]
public void When_An_Order_Is_Placed()
{
_warehouseRepo = new Mock<IWarehouseRepo>();
_warehouse = new Warehouse() { Items = 20 };
_order = new Order(_warehouseRepo.Object);
_order.WarehouseBuilder = () => _warehouse;
_order.AddOrderItems(5);
}
[Test]
public void Then_The_Order_Now_Has_5_Items()
{
Assert.That(_order.Items, Is.EqualTo(5));
}
[Test]
public void Then_The_Warehouse_Now_Has_15_Items()
{
Assert.That(_warehouse.Items, Is.EqualTo(15));
}
}
public interface IWarehouseRepo
{
void Load(Warehouse warehouse);
}
And secondly the callback approach, code and tests: (Smarts in the callback)
public class Order
{
private readonly IWarehouseRepo _repo;
public int Items { get; private set; }
public Order(IWarehouseRepo repo)
{
_repo = repo;
}
public void AddOrderItems(int numberOfItems)
{
var warehouse = new Warehouse();
_repo.Load(warehouse);
warehouse.RemoveStock(numberOfItems);
Items += numberOfItems;
}
}
public class Warehouse
{
public int Items { get; set; }
public void RemoveStock(int numberOfItems)
{
Items -= numberOfItems;
}
}
[TestFixture]
public class Given_A_Warehouse_With_20_Items
{
private Order _order;
private Mock<IWarehouseRepo> _warehouseRepo;
private Warehouse _warehouse;
[SetUp]
public void When_An_Order_Is_Placed()
{
_warehouseRepo = new Mock<IWarehouseRepo>();
_warehouseRepo.Setup(repo => repo.Load(It.IsAny<Warehouse>())).Callback<Warehouse>(warehouseArgument =>
{
warehouseArgument.Items = 20;
_warehouse = warehouseArgument;
}
);
_order = new Order(_warehouseRepo.Object);
_order.AddOrderItems(5);
}
[Test]
public void Then_The_Order_Now_Has_5_Items()
{
Assert.That(_order.Items, Is.EqualTo(5));
}
[Test]
public void Then_The_Warehouse_Now_Has_15_Items()
{
Assert.That(_warehouse.Items, Is.EqualTo(15));
}
}
public interface IWarehouseRepo
{
void Load(Warehouse warehouse);
}
Adding public state to make testing easier is a valid technique when used correctly. Likewise living with complex tests, while letting the production code remain intact is also completely valid. Both can be wrong also, so a third option is to also look at your design. In reality which you chose depends on a variety of factors. Beware anyone who states the one true way.
Public State
Adding public state is nice because it's easy, but poor because it wouldn't exist there if you weren't writing automated tests against the code. Usually this makes sense when you get hold of some legacy code and adding some additional fields isn't a big deal. If you make these read only you can limit the reach of these fields also. Interestingly in software this technique isn't used as much as it should be. In the field of hardware, circuitry and the like are physically shipped with testing components still attached. These are never used once shipped.
Complex Tests
This tends to be the most common form you see. Messy or complex tests that do anything to get the tests to work. The nice thing here is at least the design isn't compromised with public fields just for the sake of testing, but the downside as you've noted is somewhat complex and ugly tests. You can offset this by using SUT builders or simply refactoring your tests as you go, such as extracting helpers to hide the messier parts. If you do this you can at least retain the benefits of clean code and cleaner tests.
Look at the Design
Sadly the most underused but would have solved your problem. Tests hard to write? Then your design can do with improving. If the tests for new code requires public state to make it easy to test? Then your design can do with improving.
Your Example
In your case it makes sense to go with the lesser of two evils. The complex tests using the callback would be my personal recommendation. Simply when you weigh up the pros and cons of above. Yeah the test looks complex, and due to the tooling your using it has some rather gnarly syntax but it's not the end of the world.
If you really cannot change how you load the warehouse assuming either a 3rd party dependency or other reason there is another option. Create your own warehouse repository that would hide the command aspect and return a new warehouse instance. You would now have a query which you could then stub easily and side step the problems above. Sadly this would introduce a new component so you need to weigh this up. If you can change the component to become a query, I'd recommend that first.
The Func isn't really public state in my opinion. It's not a field. It's a rather novel hack around the fact the design is wrong.
How about neither. Bear with me as I walk through my thought process here. This looks more like an issue with design. I am reminded of an article I read recently about how new is glue in that Order should not couple itself with having to new up an instance of Warehouse or be responsible for exposing some way to configure it (SRP). I initially thought of adding a new dependency, something like a factory.
public interface IFactory<T> where T: class {
T Create();
}
but then though against it as that would just be adding more gunk into the class. My thoughts were focused on avoiding the introduction of additional items into the SUT.
The thing is,...based on your example the SUT needed a way to be able to create a Warehouse and load it up but not be responsible for it while keeping it self relatively lean. Then I started thinking...Whose job/responsibility is it to manage Warehouse...
The IWarehouseRepo jumped out at me and then I remembered a pattern I saw in the Entity Framework's IDbSet.
public interface IWarehouseRepo {
Warehouse Create();
void Load(Warehouse warehouse);
}
Couldn't shake the feeling that I was overthinking the problem and ended up with something like this
//My job is to provide a loaded warehouse to those who want one.
public interface IWarehouseProvider {
Warehouse GetWarehouse();
}
which would provide an already loaded Warehouse to be used by the order. Which is all it really wanted in the first place.
public class Order {
private readonly IWarehouseProvider provider;
public int Items { get; private set; }
public Order(IWarehouseProvider provider) {
this.provider = provider;
}
public void AddOrderItems(int numberOfItems) {
//get a pre-loaded warehouse
var warehouse = provider.GetWarehouse();
warehouse.RemoveStock(numberOfItems);
Items += numberOfItems;
}
}
The order shouldn't care about creating or Loading a warehouse. It just wants a Warehouse to fulfill it's order. Why over complicate things. We had a good arrangement, now you want to get clingy. (I digress)
[TestFixture]
public class Given_A_Warehouse_With_20_Items
{
private Order _order;
private Mock<IWarehouseProvider> _warehouseProvider;
private Warehouse _warehouse;
[SetUp]
public void When_An_Order_Is_Placed() {
_warehouse = new Warehouse() { Items = 20 };
_warehouseProvider = new Mock<IWarehouseProvider>();
_warehouseProvider.Setup(provider => provider.GetWarehouse()).Returns(_warehouse);
_order = new Order(_warehouseProvider.Object);
_order.AddOrderItems(5);
}
[Test]
public void Then_The_Order_Now_Has_5_Items() {
Assert.That(_order.Items, Is.EqualTo(5));
}
[Test]
public void Then_The_Warehouse_Now_Has_15_Items() {
Assert.That(_warehouse.Items, Is.EqualTo(15));
}
}
For me the thing that eventually lit the light bulb was you test. I decided to work backwards with what you were trying to test.
Given A Warehouse With 20 Items
Sure the thought process may be flawed, but the Order class just wanted a loaded Warehouse and could care less about how it was created or loaded. I could be spinning top in mud as this still looks like the Factory pattern to me.
Edit. A potential provider can then look like this
public class DefaultWarehouseProvider : IWarehouseProvder {
private readonly IWarehouseRepo repo;
public DefaultWarehouseProvider(IWarehouseRepo repo) {
this.repo = repo;
}
public Warehouse GetWarehouse() {
var warehouse = new Warehouse
repo.Load(warehouse);
return warehouse;
}
}
Does this look like what you had before? Yes, yes it does. The thing now is that it is abstracted away into its own domain allowing its dependents to carry on with their tasks without concerns for how the sausage is made. You isolate/quarantine your constraints so that they don't go around spreading their code smell disease. :)

Unit testing methods in the Presenter, MVP

Im trying to test a method which composes a collection of controls. It calls two methods:
Copies the original collection.
Sorts the new collection.
Ideally id like to be able to pass in a collection and test to see thats it sorts it correctly. Id also like to verify that method 1) is called twice, see below attempt based on the following:
Example using RhinoMock
The following test is producing errors when i try to create an instance of MainPresenter. General jist of the errors are "Can not convert from Moq.Mock to "FrazerMann.CsvImporter.UserInterface.IMainForm. + a similar one for IFileDialog.
[Test]
public void ComposeCollectionOfControls_CallSequence_4Calls()
{
var main = new Mock<IMainForm>();
var dialog = new Mock<IFileDialog>();
var temp = new Mock<IMainPresenter>();
temp.Setup(s => s.PopulateLists<Control>(It.IsAny<TableLayoutPanel>(), It.IsAny<List<Control>>()));
var testObject = new MainPresenter(main.Object, dialog.Object);
testObject.ComposeCollectionOfControls(It.IsAny<object>(), It.IsAny<EventArgs>());
temp.Verify(v => v.PopulateLists<Control>(It.IsAny<TableLayoutPanel>(), It.IsAny<List<Control>>()), Times.Once());
}
I would like to test the ComposeCollectionOfControls to ensure PopulateList() is called twice.
public interface IMainPresenter
{
void PopulateLists<T>(TableLayoutPanel userInputs, List<T> container) where T : Control;
int SortList<T>(T control1, T control2) where T : Control;
}
public class MainPresenter:IMainPresenter
{
UserInputEntity inputs;
IFileDialog _dialog;
IMainForm _view;
public MainPresenter(IMainForm view, IFileDialog dialog)
{
_view = view;
_dialog = dialog;
view.ComposeCollectionOfControls += ComposeCollectionOfControls;
view.SelectCsvFilePath += SelectCsvFilePath;
view.SelectErrorLogFilePath += SelectErrorLogFilePath;
view.DataVerification += DataVerification;
}
public void ComposeCollectionOfControls(object sender, EventArgs e)
{
PopulateLists<TextBox>(_view.ColumnNameCtrls, _view.SortedColumnNameCtrls);
_view.SortedColumnNameCtrls.Sort(SortList<TextBox>);
PopulateLists<ComboBox>(_view.ColumnDataTypeCtrls, _view.SortedColumnDataTypeCtrls);
_view.SortedColumnDataTypeCtrls.Sort(SortList<ComboBox>);
}
}
Could someone please give me some pointers as to how this should be done?
The error you are seeing is because your are passing the mock class itself (which is of type Moq.Mock) rather than the mocked object that Moq creates for you.
Instead of:
var testObject = new MainPresenter(main, dialog);
you need:
var testObject = new MainPresenter(main.Object, dialog.Object);
As an aside, it is usually considered bad practice to explicitly verify things like the number of calls made on a particular method. This leads to a tight coupling between your tests and a particular implementation, and consequently brittle tests.
By testing how many times you call a method you will often find a test failing after you refactor some code when the end result of the code is still correct.
It is much better to test the final state of the objects involved, and make your tests ignorant of how that state was reached.

Moq - mock.Object.MyMethod mocking does not work

I have a strange trouble. I am not too familiar with Moq, being more a GUI guy. I tried to mock a factory method in my code. The factory looks like this, and returns a ISettings instance which does many IO Operations. I want it to return a memory only ISettings instance to accelerate my test.
public class SettingsFactory
{
internal ISettings mSettingsImpl;
internal virtual ISettings CreateOrGetSettings()
{
return mSettingsImpl ?? (mSettingsImpl = new XmlSettings());
}
}
and the mock is
var imocked = new Mock<SettingsFactory>() {CallBase = false};
imocked.Setup(x => x.CreateOrGetSettings()).Returns(new NonPersistingSettings());
var tryToSeeTheType = imocked.Object.CreateOrGetSettings();
the tryToSeeTheType is however XMLSettings and not NonPersistingSettings as I would expect. Stepping through results into the code shown me that it goes directly into the original factory method. Any suggestions what I do wrong here?
The "Object" property of a mocked object is not actually an instance of the class you are trying to mock.
The purpose of a mock is to be able to replace an object the method you are trying to test depends on.
Imagine that your SettingsFactory performs very expensive operations like for example accessing the network or a database or the file system. You do not want your test to access those expensive resources so you create a mock. I would be something like this:
public class ClassThatUsesSettingsFactory
{
private readonly SettingsFactory _settingsFactory;
public ClassThatUsesSettingsFactory(SettingsFactory settingsFactory)
{
_settingsFactory = settingsFactory;
}
public void MethodThatCallsSettingsFactory()
{
//... do something
var settings = _settingsFactory.CreateOrGetSettings();
//... do something
}
}
By doing this you are able to replace the SettingsFactory with a mock on your unit test like so:
[TestMethod]
public void MakeSureSettingsFactoryIsCalled()
{
var settingsFactoryMock = new Mock<SettingsFactory>();
settingsFactoryMock.Setup(f => f.CreateOrGetSettings(), Times.Once).Verifiable();
var subjectUnderTest = new ClassThatUsesSettingsFactory(settingsFactoryMock.Object);
subjectUnderTest.MethodThatCallsSettingsFactory();
settingsFactoryMock.Verify();
}
This unit test is basically only making sure that the method CreateOrGetSettings gets called once and only once when the MethodThatCallsSettingsFactory gets executed.
What Moq does is to create a different class with a different implementation of its virtual method that will, most likely, set a flag to true once it gets called and then check the value of that flag on the "Verify" method.
There is a lot to grasp here so I hope it is clear enough since you mentioned that you do not have a lot of experience with Moq.

How to use moq to test code that calls protected helpers

I currently run tests that look like the following:
// In Blah.cs
public class ClassUnderTest
{
public bool MethodUnderTest()
{
// Do a bunch of stuff...
return HelperMethod();
}
protected virtual bool HelperMethod()
{
bool success = false;
// Proprietary Hardware Access.
// Database Calls.
// File System Modifications.
return success;
}
}
// In TestBlah.cs
public class TestStub : ClassUnderTest
{
public bool HelperMethodReturnValue;
protected override bool HelperMethod()
{
return HelperMethodReturnValue;
}
}
[TestClass]
public class TestingClass
{
[TestMethod]
public void ClassUnderTest_MethodUnderTest_TestHelperReturnsTrue()
{
var stub = new TestStub();
stub.HelperMethodReturnValue = true;
Assert.IsTrue(stub.MethodUnderTest());
}
[TestMethod]
public void ClassUnderTest_MethodUnderTest_TestHelperReturnsFalse()
{
var stub = new TestStub();
stub.HelperMethodReturnValue = false;
Assert.IsFalse(stub.MethodUnderTest());
}
}
The above looks fine for simple things, however the stub class gets exponentially bigger and more complex quickly.
I'd like to replace the stub class using Moq. However this won't compile because for some reason I can't set a return value on a protected method.
[TestMethod]
public void ClassUnderTest_MethodUnderTest_TestHelperReturnsFalse()
{
var mockClass = new Mock<ClassUnderTest>();
mockClass.Protected().Setup("HelperMethod").Returns(false);
Assert.IsFalse(mockClass.Object.MethodUnderTest());
}
Anyone know how I'd go about doing this? Can I do this with moq?
Looking at the moq source code I'd guess you need to explicitly call the generic version of Setup. The non-generic version seems to be used for void methods. So try
mockClass.Protected().Setup<bool>("HelperMethod").Returns(false);
Beside this, I'd recommend re-thinking your class design. If HelperMethod() is doing such a bunch of things it would be worth its own class that is injected as a dependency into ClassUnderTest. Testing a mock object, instead of using a mock object to test something "real", is not what mocking frameworks are made for (not in the first place, at least).
Protected methods are not a great way of isolating dependencies, but it does sometimes come up, particularly when adapting legacy code for testability. One option that avoids the awkward string-based Moq syntax is to make the method 'protected internal' (or just 'internal' if you don't intend to override it in normal usage from other assemblies.) You then use InternalsVisibleTo on the assembly to expose the method. This is a bit of a hack, but using a protected method for this purpose is already a bit of a hack. In some ways I prefer the 'internal' approach, as it makes it clear that this is a backdoor method that you're not supposed to use (except for testing), as opposed to a protected method that you might expect to override in normal usage.

How do I mock a private field?

I'm really new to mocks and am trying to replace a private field with a mock object. Currently the instance of the private field is created in the constructor. My code looks like...
public class Cache {
private ISnapshot _lastest_snapshot;
public ISnapshot LatestSnapshot {
get { return this._lastest_snapshot; }
private set { this._latest_snapshot = value; }
}
public Cache() {
this.LatestSnapshot = new Snapshot();
}
public void Freeze(IUpdates Updates) {
ISnapshot _next = this.LastestSnapshot.CreateNext();
_next.FreezeFrom(Updates);
this.LastestSnapshot = _next;
}
}
What I'm trying to do is create a unit test that asserts ISnapshot.FreezeFrom(IUpdates) is called from within Cache.Freeze(IUpdates). I'm guessing I should replace the private field _latest_snapshot with a mock object (maybe wrong assumption?). How would I go about that while still retaining a parameterless constructor and not resorting to making LatestSnapshot's set public?
If I'm totally going about writing the test the wrong way then please do point out as well.
The actual implementation of ISnapshot.FreezeFrom itself calls a heirarchy of other methods with a deep object graph so I'm not too keen on asserting the object graph.
Thanks in advance.
I'm almost citing techniques from "Working Effectively with Legacy Code":
Sub-class your class in a unit test and supersede your private variable with a mock object in it (by adding a public setter or in the constructor). You probably have to make the variable protected.
Make a protected getter for this private variable, and override it in testing subclass to return a mock object instead of the actual private variable.
Create a protected factory method for creating ISnapshot object, and override it in testing subclass to return an instance of a mock object instead of the real one. This way the constructor will get the right value from the start.
Parametrize constructor to take an instance of ISnapshot.
I'm not sure that you can do that. If you're wanting to test _next then you're probably going to have to pass it in as a parameter and then in your unit test pass in a Mock object which you can then test using an Expectation. That's what I'd be doing if I were trying to do it in Moq.
As an example of what I might try using the Moq framework:
Mock<ISnapshot> snapshotMock = new Mock<ISnapshot>();
snapshotMock.Expect(p => p.FreezeFrom(expectedUpdate)).AtMostOnce();
Cache c = new Cache(snapshotMock.Object);
c.Freeze(expectedUpdate);
Note: I haven't tried to compile the above code. Its just there to give an example of how I'd approach solving this.
I don't think you'd need to mock private member variables. Isn't the whole idea of mocking that the public interface for an object works as expected? Private variables are implementation details that mocks aren't concerned with.
This answer might be simple, but looking at the code, is there any way in which ISnapshot.FreezeFrom(IUpdates) is not going to be called? Sounds like you want to assert something that will always be true.
As Jason says, mocking is meant for situations where your class depends on SomeInterface to do it's work, and you want to test YourClass in isolation from whichever implementation of SomeInterface you actually use at runtime.
The question to ask is: what are the externally visible effects if this worked?
What happens to all those Snapshots? One option might to initialise the Cache with its first Snapshot from outside, say in the constructor. Another might be to mock whatever it is that the Snapshot calls that matters outside the cache. It depends on what you care that happens.
It might be too late to respond. Anyways. I also had similar problem.
public class Model
{
public ISomeClass XYZ{
get;
private set;
}
}
I required to set value of XYZ in my test case. I resolved the problem using this syntex.
Expect.Call(_model.XYZ).Return(new SomeClass());
_repository.ReplayAll();
In the case above we can do it like this
Expect.Call(_cache.LatestSnapshot).Return(new Snapshot());
_repository.ReplayAll();
You will probably have to refactor your class like this, in order for it to be injected with a different dependency for ISnapshot. Your class will remain to function the same.
public class Cache {
private ISnapshot _lastest_snapshot;
public ISnapshot LatestSnapshot {
get { return this._lastest_snapshot; }
private set { this._latest_snapshot = value; }
}
public Cache() : this (new Snapshot()) {
}
public Cache(ISnapshot latestSnapshot) {
this.LatestSnapshot = latestSnapshot;
}
public void Freeze(IUpdates Updates) {
ISnapshot _next = this.LastestSnapshot.CreateNext();
_next.FreezeFrom(Updates);
this.LastestSnapshot = _next;
}
}
You can simply add "setSnapshot(ISnapshot)" method to the Cache with your mocked class instance.
You can also add a constructor that takes ISnapshot.
Turn Cache into a template as shown below.
template <typename T=ISnapshot>
public class Cache {
private T _lastest_snapshot;
public T LatestSnapshot {
get { return this._lastest_snapshot; }
private set { this._latest_snapshot = value; }
}
public Cache() {
this.LatestSnapshot = new Snapshot();
}
public void Freeze(IUpdates Updates) {
T _next = this.LastestSnapshot.CreateNext();
_next.FreezeFrom(Updates);
this.LastestSnapshot = _next;
}
}
In production code do:
Cache<> foo;//OR
Cache<ISnapshot> bar;
In test code do:
Cache<MockSnapshot> mockFoo;

Categories