I have a class like this:
public class Customer : CustomerBase
{
// internals are visible to test
internal string GenString()
{
// this actually composes a number of different properties
// from the parent, child and system properties
return this.InfoProperty.Name + DateTime.Now.ToString() + "something else";
}
}
// this class is in a 3rd party library, but from metadata it looks like this
public class CustomerBase
{
public Info InfoProperty { get; }
}
My test looks something like this:
public class Tests
{
public void MyTest()
{
using (ShimsContext.Create())
{
// Arrange
/* I shim datetime etc. static calls */
Fakes.StubCustomer c = new Fakes.StubCustomer()
{
InfoProperty = new Info("Name") // <- Error here because it's readonly
};
// Act
string result = c.GenString();
// Assert
Assert.AreEqual(result, "whatnot");
}
}
}
So my question is, how can I stub/shim the readonly property so that I can test this function?
What about wrapping this getter in an ad hoc virtual method that could be overrided by a mock?
Eg:
public class Customer : CustomerBase
{
// internals are visible to test
internal string GenString()
{
// this actually composes a number of different properties
// from the parent, child and system properties
return InfoPropertyNameGetter() + DateTime.Now.ToString() + "something else";
}
public virtual string InfoPropertyNameGetter(){
retrn this.InfoProperty.Name;
}
}
Mock<Customer> mock = new Mock<Customer>();
mock.Setup(m => m.InfoPropertyNameGetter()).Returns("My custom value");
It would look a bit like the Introduce Instance Delegator pattern described in Working effectively with legacy code
Related
I have a bunch of data fetchers which all has the almost same signature. The only thing that differs is the return type. The return type is specified as T:
I have this interface:
public interface IDataFetcher<T>
{
T FetchData(MyObject data);
}
Next I have a about 10 implementations of this interface. In de the calling code I want to do something like this:
public class FetchCommandHandler
{
private readonly IEnumerable<IDataFetcher<T>> _fetchers;
public FetchCommandHandler(IEnumerable<IDataFetcher<T>> fetchers) // this of course does not work
{
_fetchers = fetchers;
}
public MyResult Handle()
{
var myObj = new MyObject(); // get object from database
foreach(var fetcher in _fetchers)
{
var result = fetcher.FetchData(myObj);
// do something with result
}
}
}
So, in the end, what I want is not have to inject each DataFetcher<T> implementation in the constructor. I am looking for a way to retreive all the registrations of IDataFetcher<T> from StructureMap.
I am open for every other design that achieves the same result, ie, not inject each implementation in the constructor.
What we can do is introduce another interface for return type and all the types that will be returned will implement it.
Define an interface :
public interface IData
{
}
public interface IDataFetcher<T> where T : IData
{
T FetchData(MyObject data);
}
As an example a type that would be returned:
public class FooData : IData
{
}
and it's DataFetcher implementation will look like:
public class FooDataFetcher : IDataFetcher<FooData>
{
public FooData FetchData(MyObject data)
{
// logic here and return instance of FooData
}
}
Now what we can do is define the Handler class something like:
public class FetchCommandHandler
{
private readonly IEnumerable<IDataFetcher<IData>> _fetchers;
public FetchCommandHandler(IEnumerable<IDataFetcher<IData>> fetchers) // this of course does not work
{
_fetchers = fetchers;
}
public MyResult Handle()
{
var myObj = new MyObject(); // get object from database
foreach(var fetcher in _fetchers)
{
var result = fetcher.FetchData(myObj);
// do something with result
}
}
}
Say I have a class that is being called from within my MainClass method that I am testing.
public class MainClass
{
private readonly SubClass;
// constructor not shown
public method TestMethod()
{
var data = SubClass.MethodA();
// ...some code
var moreData = SubClass.MethodB(someOtherData);
// ...more code
}
}
Using RhinoMock, I'd like to create a stub for SubClass.MethodA() to return a specified set of data in the test, however when calling SubClass.MethodB(), I want to call the original implementation.
I wouldn't want to break out the SubClass' two methods out into their own classes as they fit in SubClass. Is there a way in RhinoMock to stub out one method while calling another method in the same class (that is not a stub)?
I would use the extract and override test pattern and a simple stub for this.
This doesn't explicitly use Rhino though but will do for your scenario.
If you don't want to go down this path consider injecting Subclass into MainClass via a constuctor, public setter or parameter, and then you can have more control of mocking subclass first.
The idea is to make a virtual method that a sub class stub can override to take control of the behaviour of a part of a class under test.
public class MainClass
{
private readonly SubClass _subClass;
// constructor not shown
public void TestMethod()
{
var data = SubClassMethodACall();
// ...some code
var someOtherData = "";
var moreData = _subClass.MethodB(someOtherData);
// ...more code
}
protected virtual string SubClassMethodACall()
{
return _subClass.MethodA();
}
}
public class SubClass
{
public string MethodA()
{
return null;
}
public string MethodB(string s)
{
return null;
}
}
namespace Tests.Unit
{
public class MainClassStub : MainClass
{
private readonly string _returnValueForMethodA;
public MainClassStub(string returnValueForMethodA)
{
_returnValueForMethodA = returnValueForMethodA;
}
protected override string SubClassMethodACall()
{
return _returnValueForMethodA;
}
}
[TestFixture]
public class TestClass
{
[Test]
public void TestMethod()
{
var mainClass = new MainClassStub("this is the test value returned");
//.. rest of test
}
}
}
I wish to test a method which queries a third-party library. The library returns an object with a IReadOnlyCollection property.
There is no constructor to set the value of the property and the object has no interface for me to mock.
I have used Moq to mock the interface for the service that I call, but I can't create a mocked return value as I can't set the property.
public interface IHitService {
public Hit GetHit();
}
public class Hit {
public Hit() {
}
public IReadOnlyCollection<string> Result { get; }
}
public class TestingClass {
public void MyTest() {
Hit hit = new Hit() {
// cannot set this property
Result = new List<string>() { "hello","goodbye" };
}
Mock<IHitService> service = new Mock<IHitService>();
service.Setup(c => c.GetHit).Returns(hit);
}
}
What would be the best way for me to generate the return value to test my method? Wrapping the object with a new property to hide the base does not work.
You can use unit-test frameworks that allow you to change the behavior of a concrete object, for example in this case i used Typemock Isolator to try and solve your issue, it allows you to change the the return value of the result property so can "set" for your test without changing your code or adding extra code:
public void TestMethod1()
{
List<string> s = new List<string> { "sfas", "asfsa", "blbba" };
var hit = Isolate.Fake.NextInstance<Hit>();
Isolate.WhenCalled(() => hit.Result).WillReturnCollectionValuesOf(s);
}
In this test i mocked the Hit class and modified the return value of the Result property to a list of strings i created.
If you need to test a third-party library, it would be a better idea to create your own abstraction (interface) and rely on that for both testing and real code:
public interface IHitService
{
IHit GetHit();
}
public interface IHit
{
IReadOnlyCollection<string> Result { get; }
}
In your application code, you can create a simple wrapper class that implements IHit by delegating to the concrete third-party class. Now you can test the interface by mocking it as needed.
In general, if you can't change 3rd party code, build an adapter to it and use your own abstraction :-
public interface IHit
{
IReadOnlyCollection<string> Result { get; }
}
public interface IHitService
{
IHit GetHit();
}
public class HitAdapter : IHit
{
private Hit _hit;
public HitAdapter(Hit hit)
{
_hit = hit;
}
public IReadOnlyCollection<string> Result => _hit.Result;
}
public class TestingClass
{
public void MyTest()
{
var hitMock = new Mock<IHit>();
hitMock.Setup(c => c.Result).Returns<IReadOnlyCollection<string>>(x => new List<string>() {"hello", "goodbye"});
var service = new Mock<IHitService>();
service.Setup(c => c.GetHit()).Returns<IHit>(x => hitMock.Object);
}
}
I have these interfaces
public interface Interface1 { Interface2 Items {get;} }
public interface Interface2 { Guid? ApplicationTypeId { get; } }
public interface Interface3 { Class1 Item {get;} }
public interface Interface4 { Guid? ApplicationId { get; set; } }
A class inherits the first interface
public class Class1 : Interface1 {
public Interface2 Items { get; }
}
Another class which consists of few guids
public static class ContentTypeIds
{
public static Guid ContentGuid1 => new Guid("{11798e9d-a167-4cfc-8cfa-9a24fd6caf25}");
public static Guid ContentGuid2 => new Guid("{7d22f5bb-37fd-445a-b322-2fa1b108d260}");
}
I need to unit test the following property
private readonly Interface3 _interface3;
public Ticket Current
{
get
{
//This line is very complicated
Interface4 itemByContentType = _interface3.Item?.Items.GetItemByContentType(ContentTypeIds.ContentGuid2);
if ( itemByContentType?.ContentId != null )
return Get(itemByContentType.ContentId.Value);
return null;
}
}
My test class goes here
[Test]
public class TestClass {
var mock1 = new Mock<Interface1>();
var mock2 = new Mock<Interface2>();
var mock3 = new Mock<Interface3>();
mock1.SetupAllProperties();
mock2.SetupAllProperties();
mock3.SetupAllProperties();
}
The value for 'itemByContentType' goes null.
Could anyone help me to make it simple and testable as it is getting complicated to test this property? I'm using Moq. I will appreciate any help.
Thanks
I'm not an expert on Moq, but it looks like its SetupAllProperties method simply sets up all the properties to act like properties (i.e. the object it creates has a persistent member which can support GET/SET operation). If this isn't done, then as I understand it, the properties will still be available, but they'll always resolve to null. This is very handy when preparing the Mock objects, but on its own, though, that doesn't setup the properties with any sort of value.
I think what you should be doing is using Moq's SetupGet in conjunction with the Returns method to prepare the GET of the Items property with a specific value.
Here is some (simplified) sample code, to demonstrate this:
public interface IFoo { Guid? ApplicationId { get; set; } }
public interface IBar { IFoo Items { get; } }
class Program
{
static void Main(string[] args)
{
// SETUP
// Prepare mocks
Mock<IFoo> MockFoo = new Mock<IFoo>();
Mock<IBar> MockBar = new Mock<IBar>();
// Seting up properties allows us read/write Foo's ApplicationId
MockFoo.SetupAllProperties();
// The mocked Foo object should be what's returned when Items is requested
var expectedFoo = MockFoo.Object;
// Setup the Bar object to return that mocked Foo
MockBar.SetupGet(x => x.Items).Returns(expectedFoo);
// The value written here will be persistent due to SetupAllProperties
expectedFoo.ApplicationId = new Guid("{7d22f5bb-37fd-445a-b322-2fa1b108d260}");
// ACTION
// When the "Items" property is accessed, the IFoo we get should be what we mocked...
var actualFoo = MockBar.Object.Items;
// ... and we can read the value set to Foo's ApplicationId
var actualAppId = actualFoo.ApplicationId;
}
}
I'm trying to write a unit test for one of my classes that uses a base class from a third party library, but my first attempt is fragile as the tests depend on integration with texts managed by content managers.
First, a small repro. This will represent the third party base class I have to work with:
namespace ThirdPartyXyz
{
public class SomeFancyBaseClass
{
public SomeFancyBaseClass()
{
this.myMap = new Dictionary<string, string> { { "title", "Greatness" } };
}
public IReadOnlyDictionary<string, string> myMap { get; private set; }
}
}
Then I'm unit testing code along these lines:
namespace MyCorp
{
public class MyThing : ThirdPartyXyz.SomeFancyBaseClass
{
public string GetHeadline()
{
return "[" + this.myMap["title"] + "]";
}
}
}
With the following NUnit test method:
namespace MyCorp.UnitTestExperiments
{
[TestFixture]
public class MyThingTests
{
[Test]
public void GetHeadlineWillOutputBracketedResource()
{
var thing = new MyThing();
var result = thing.GetHeadline();
Assert.That(result, Is.EqualTo("[Greatness]"));
}
}
}
This is green, but will turn red if a content manager changes the "Greatness" value to something else. So I'm trying to mock / stub / fake the actual dictionary from the base class, but this is not straightforward because the third party library declares myMap's dictionary setter as private.
Here's what I've tried:
namespace MyCorp.UnitTestExperiments
{
[TestFixture]
public class MyThingTests
{
private class TestableMyThing : MyThing
{
public TestableMyThing(Dictionary<string, string> texts) { this.myMap = texts; }
public new IReadOnlyDictionary<string, string> myMap { get; private set; }
}
[Test]
public void GetHeadlineWillOutputBracketedResource()
{
var fakeTexts = new Dictionary<string, string> { { "title", "test text" } };
var thing = new TestableMyThing(fakeTexts);
var result = thing.GetHeadline();
Assert.That(result, Is.EqualTo("[test text]"));
}
}
}
However, this doesn't work: the test still fails. The GetHeadline method uses the hidden myMap property from SomeFancyBaseClass as opposed to the fake dictionary containing the "test text".
My goals / questions currently are two-fold. First, by now I'm curious how I (c/w)ould get my current approach to work. But second, I fear my way of making MyThing testable is not the best one, and would like to know if there's a way to avoid this situation altogether.
Three options:
Use reflection to access the seter of the dictionary
Second option, make your class more easily to stub:
public class MyThing : ThirdPartyXyz.SomeFancyBaseClass
{
public virtual new IReadOnlyDictionary<string, string> myMap;
{
get { return base.myMap; }
}
public string GetHeadline()
{
// this will use your 'virtual new myMap'!
return "[" + this.myMap["title"] + "]";
}
}
Now in your unit tests you can:
public class MyThingTestable : MyThing
{
public override IReadOnlyDictionary<string, string> myMap { get; set; }
}
and now you can set the myMap, and your class will use it (but note that the SomeFancyBaseClass class won't use it! It will use its myMap! Not very good!)
Third option: use Microsoft Fakes or similar product.