Using this generic base class:
public abstract class Logic<U> where U : class
{
protected U m_provider;
public Logic(U provider)
{
m_provider = provider;
}
}
I’m trying to create a base test class for unit test:
public class LogicBaseTest<T, U> where T : Logic <U>, new() where U: class
{
protected T m_logic;
protected U m_provider;
[OneTimeSetUp]
public virtual void OneTimeSetup()
{
m_provider = (U)Substitute.For<IInterface>();
m_logic = new T(m_provider);
}
}
It complains on the constructor, it requests for the new() constrain but when I add it then it complains that the constructor cannot take parameters.
I could add a method to populate the provider but I’m wondering whether it could be done in the constructor.
>Solution :
So you have two problems here:
- LogicBaseTest needs to know how to instantiate a
Logic<U>. Logic<U>requires aUin the constructor.
My proposed solution to it is to pass a factory delegate into the base test class and remove the new() requirement. Then your setup can construct the Logic class using the factory:
public class LogicBaseTest<T, U>
where T : Logic<U>
where U: class
{
protected readonly Func<U, T> _factory;
public LogicBaseTest(Func<U, T> factory)
{
_factory = factory;
}
[OneTimeSetUp]
public virtual void OneTimeSetup()
{
m_provider = (U)Substitute.For<IInterface>();
m_logic = _factory(m_provider);
}
}
In the derived test class you just have to tell the base class how to new up a Logic<U>:
public class DerivedTest : LogicBaseTest<Logic<MyUType>, MyUType>
{
public DerivedTest()
: this(u => new Logic<MyUType>(u))
{
}
}