Reputation: 527
Very simplified version of code:
interface IFactory
{
ITreasure Get(SomeData data);
}
class Factory : IFactory
{
ITreasure Get(SomeData data)
{
// Create instance of ITreasure in very long chain of methods basing on "data"
// Can produce one of: BlueTreasure, RedTreasure or GreenTreasure
return treasure;
}
}
And here it is, the class with smell that I can not modify at all.
class CantModify
{
public CantModify {}
public TestMe(SomeData data)
{
ITreasure treasure = new Factory().Get(data);
if(treasure is BlueTreasure) ...
else if(treasure is RedTreasure) ...
else if(treasure is GreenTreasure) ...
}
}
I would like to test all code paths of TestMe() but I don't want to prepare data to obtain specific type of ITreasure. Is there any way to make new Factory() return Mocked instance of Factory that will return different type of ITreasure in each test?
Upvotes: 2
Views: 63
Reputation: 745
You can mock all future instances of Factory
and by that you will be able to modify the behavior of Get
method to fit in your test, for example I used Typemock isolator to create a test that check if the treasure
is green:
public string TestMe(SomeData data)
{
ITreasure treasure = new Factory().Get(data);
if (treasure is BlueTreasure) { return "blue"; }
else if (treasure is RedTreasure) { return "red"; }
else if (treasure is GreenTreasure) { return "green"; }
return null;
}
[TestMethod,Isolated]
public void TestMethod1()
{
var fakeFactory = Isolate.Fake.AllInstances<Factory>();
var green = new GreenTreasure();
Isolate.WhenCalled(() => fakeFactory.Get(null)).WillReturn(green);
var res = new CantModify().TestMe(new SomeData());
Assert.AreEqual("green", res);
}
Upvotes: 1
Reputation: 119
You need to add dependency on IFactory in the Cantmodify class. And then you can Mock Get Method to return whatever you want. The class should look :
public class CantModify
{
private readonly IFactory _factory;
public CantModify(IFactory factory)
{
_factory = factory;
}
public TestMe(SomeData data)
{
ITreasure treasure = _factory.Get(data);
if (treasure is BlueTreasure) ...
else if (treasure is RedTreasure) ...
else if (treasure is GreenTreasure) ...
}
Upvotes: 1