You could try something like below (exact syntax not checked with
anything). It doesn't change your concrete class to deal with
injection, but still allows testers to do so, and you don't need to
add a new constructor for your Concrete class. Non-test code will use
the proxy created by the class itself, and test code can inject it's
own.
// Class Under Test:
public class ConcreteClass
{
protected _proxy;
public ConcreteClass()
{
_proxy = new ServiceProxy();
}
public void MethodToTest()
{
// This is a dependant class so I want to mock this
_proxy.MethodToMock();
}
}
public class ServiceProxy()
{
public void MethodToMock()
{
// do something here
}
}
//Test Code:
public class ConcreteTester : ConcreteClass()
{
public ConcreteTester(ServiceProxy proxy)
{
_proxy = proxy;
}
}
public void MethodToTestTest()
{
var mock = Mock<ServiceProxy>();
mock.Setup(serviceObject => serviceObject.MethodToMock());
ConcreteClass classUnderTest = new ConcreteTester(mock.Object);
classUnderTest.MethodToTest ();
}
It works without having to refactor *other* classes, which is what I
gathered the OP was trying to avoid, if possible. When dealing with
legacy code, I've often found it better to make small sub-optimal
choices, rather than large optimal ones, a choice which might not be
required with new code. If the goal is to get the code under test
with minimal impact to other code, this is one way to do that.
/bs
That's another way, though the test would still have to create a derived
class to use it, since it's protected. I don't see much advantage
either way, other than the amount of additional code.
/bs
True, but then so would:
private ServiceProxy _proxy;
protected Proxy { get { return _proxy; } set { _proxy = value; } }
Again, both provide what I thought the OP was requesting, i.e. a way
to test the consumer of the proxy without having to finagle other code
throughout the application. Both require that the test derive from,
and add code to, the class under test solely for the purpose of
testing that class, but from what I've seen, that's a consequence of
working with legacy code.
Which option one chooses would seem to me to be a matter of taste, as
I don't discern any compelling advantage or disadvantage to either
one. The protected property version feels simpler to *me*, but I can
recognize that might not be true for everyone.
/bs
Ah, I understand now. I wasn't trying to make that case. I guess I
was leaving the "refinement" part of it as an exercise for the reader.
At least, that's my excuse...
/bs