namespace NUnitTestAbstract
{
public abstract class BaseTestClass1
{
public abstract void BaseTestClass1Method();
}
public abstract class BaseTestClass2 : BaseTestClass1
{
// not overriding BaseTestClass1Method, child classes should do
public void SomeTestMethodA() { }
public void SomeTestMethodB() { }
}
public abstract class BaseTestClass3 : BaseTestClass1
{
// not overriding BaseTestClass1Method, child classes should do
public void SomeTestMethodX() { }
public void SomeTestMethodY() { }
}
public class TestClass2A : BaseTestClass2
{
public override void BaseTestClass1Method()
{
// do stuff
}
}
public class TestClass2B : BaseTestClass2
{
public override void BaseTestClass1Method()
{
// do same stuff as TestClassA
}
}
public class TestClass3A : BaseTestClass3
{
public override void BaseTestClass1Method()
{
// do stuff
}
}
public class TestClass3B : BaseTestClass3
{
public override void BaseTestClass1Method()
{
// do same stuff as TestClass3A
}
}
}
At this moment I have the above construction. A base class extending another base class. The base class is extended by two child classes. The implementation of BaseTestClass1Method
is the same for the two child classes. If it was possible to extends from two parents I would create a class extending BaseTestClass1
implementing BaseTestClass1Method
. The two child classes would then extend BaseTestClass2
and the new class so that I only have to implement BaseTestClass1Method
once
When I add another BaseTestClass3 (same level as BaseTestClass2) extending from BaseTestClass1 and create child classes from it, I have more duplicate code for the implementation of BasetestClass1Method.
How can I solve this with the correct pattern?
Here's a more implemented example:
namespace NUnitTestAbstract
{
public interface IServer { }
public abstract class ServerBase
{
public abstract IServer GetServerInstance();
}
public abstract class SomeTests1Base : ServerBase
{
// not overriding BaseTestClass1Method, child classes should do
public void SomeTestMethodA() { }
public void SomeTestMethodB() { }
}
public abstract class SomeTests2Base : ServerBase
{
// not overriding BaseTestClass1Method, child classes should do
public void SomeTestMethodX() { }
public void SomeTestMethodY() { }
}
public class TestClass2A : SomeTests1Base
{
public override IServer GetServerInstance()
{
IServer serverX = null;
return serverX;
}
}
public class TestClass2B : SomeTests1Base
{
public override IServer GetServerInstance()
{
IServer serverX = null;
return serverX;
}
}
public class TestClass3A : SomeTests2Base
{
public override IServer GetServerInstance()
{
IServer serverY = null;
return serverY;
}
}
public class TestClass3B : SomeTests2Base
{
public override IServer GetServerInstance()
{
IServer serverY = null;
return serverY;
}
}
}
you could implement BaseTestClass1Method in BaseTestClass2 so that both TestClassA and TestClassB get the same implementation. Depending on your requirements however, going this path might end in inheritance hell.
Instead of inheriting BaseTestClass2 from BaseTestClass1 you can pass an instance that implements BaseTestClass1 into BaseTestClass2 via its constructor (dependence injection (DI)). Then in TestClassA and TestClassB simply call the BaseTestClass1Method method of the injected in instance. This reduces your inheritance levels to just 1.
Use a DI container such as Autofac or Unity to inject the correct implentation of BaseTestClass1 into decendants of BaseTestClass2.
UPDATE
So working from your example
namespace NUnitTestAbstract
{
public interface IServer { }
public class BaseServer()
{
private IServer _server;
public BaseServer(IServer server)
{
_server = server;
}
public IServer GetServerInstance()
{
return _server;
}
}
public class SomeTests1 : ServerBase
{
// not overriding BaseTestClass1Method, child classes should do
public void SomeTestMethodA() { }
public void SomeTestMethodB() { }
}
public class SomeTests2 : ServerBase
{
// not overriding BaseTestClass1Method, child classes should do
public void SomeTestMethodX() { }
public void SomeTestMethodY() { }
}
}
public class ServerA : IServer
{
//Implementation
}
public class ServerB : IServer
{
//Implementation
}
var someTests1 = new SomeTests1(new ServerA()); var someTests2 = new SomeTests2(new ServerB());
Note that I've removed the abstract classes and injected the server implementations into the new instances.
I've dropped the TestClass(1..n) because I cannot see a need for them but only you can know the answer to that.
Also I've written this code on the fly so it has not been tested nor have I checked if it even compiles but you should be able to get the gist of it. Hope it helps.