Doing TDD and want to isolate the method under test: Direct();
However, when the test creates MyClass, SomeClass.SetupStuff(); blows up (NotImplementedException). So, modified the IMyClass interface to have a Configure(); method that can be called after MyClass construction to avoid the exception.
Question: Is this an accepted way of handling this scenario or is there some basic OOP principal that this breaks?
public class MyClass : IMyClass
{
public MyClass()
{
// class with static method that sets stuff up
SomeClass.SetupStuff();
}
public void IMyClass.Direct()
{
// want to test this
}
}
vs
public class MyClass : IMyClass
{
public MyClass()
{
}
public void IMyClass.Direct()
{
// want to test this
}
//
public void IMyClass.Configure()
{
// class with static method that sets stuff up
SomeClass.SetupStuff();
}
}
One way to avoid such problems is to use dependency injection
public class MyClass : IMyClass
{
public MyClass(ISomeClass someClass)
{
someClass.SetupStuff();
}
public void IMyClass.Direct()
{
// want to test this
}
}
By decoupling your class from SomeClass, you are free to provide a mock implementation of ISomeClass during test and can provide a full implementation at runtime.
Related
I have a base class for my tests which is composed in the following way:
[TestClass]
public abstract class MyBaseTest
{
protected static string myField = "";
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
// static field initialization
myField = "new value";
}
}
Now I am trying to create a new test that inherits from the base, with the following signature:
[TestClass]
public class MyTest : MyBaseTest
{
[TestMethod]
public void BaseMethod_ShouldHave_FieldInitialized()
{
Assert.IsTrue(myField == "new value");
}
}
The ClassInitialize is never called by the child tests ... What is the real and correct way of using test initialization with inheritance on MsTest?
Unfortunately you cannot achieve this that way because the ClassInitializeAttribute Class cannot be inherited.
An inherited attribute can be used by the sub-classes of the classes that use it. Since the ClassInitializeAttribute cannot not be inherited, when the MyTest class is initialized the ClassInitialize method from the MyBaseTest class cannot be called.
Try to solve it with another way. A less efficient way is to define again the ClassInitialize method in MyTest and just call the base method instead of duplicating the code.
A potential workaround is to define a new class with AssemblyInitializeAttribute instead. It has a different scope, obviously, but for me it meets my needs (cross-cutting concerns, which just so happen to require exactly the same settings for every test class and test method.)
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MyTests
{
[TestClass]
public sealed class TestAssemblyInitialize
{
[AssemblyInitialize]
public static void Initialize(TestContext context)
{
...
}
}
}
Use a static constructor on a base class? It's executed only once, by design, and it doesn't have the weird limitation on inheritance, like the ClassInitializeAttribute.
There is a parameter for the ClassInitialize and ClassCleanup attributes:
[ClassInitialize(InheritanceBehavior.BeforeEachDerivedClass)]
public static void ClassInitialize(TestContext context)
{
// gets called once for each class derived from this class
// on initialization
}
[ClassCleanup(InheritanceBehavior.BeforeEachDerivedClass)]
public static void Cleanup()
{
// gets called once for each class derived from this class
// on cleanup
}
which will actually do what you want.
UPDATE: Added lock to avoid multi-threading issues...
We know that a new instance of the class is constructed for every [TestMethod] in the class as it gets run. The parameter-less constructor of the base class will be called each time this happens. Couldn't you simply create a static variable in the base class and test it when constructor runs?
This helps you to not forget to put the initialization code in the sub-class.
Not sure if there's any drawback to this approach...
Like so:
public class TestBase
{
private static bool _isInitialized = false;
private object _locker = new object();
public TestBase()
{
lock (_locker)
{
if (!_isInitialized)
{
TestClassInitialize();
_isInitialized = true;
}
}
}
public void TestClassInitialize()
{
// Do one-time init stuff
}
}
public class SalesOrderTotals_Test : TestBase
{
[TestMethod]
public void TotalsCalulateWhenThereIsNoSalesTax()
{
}
[TestMethod]
public void TotalsCalulateWhenThereIsSalesTax()
{
}
}
For example I have the following classes:
1.
class MyClass1
{
public MyClass1 Method()
{
...
return new MyClass1();
}
}
class MyClass2
{
public MyClass2 Method()
{
...
return new MyClass2();
}
}
The methods have the same bodies that's why I want to extract the code and re-use.
2.
abstract class MyClass
{
protected void Method()
{
...
}
}
class MyClass1 : MyClass
{
public MyClass1 Method()
{
base.Method();
return new MyClass1();
}
}
class MyClass2 : MyClass
{
public MyClass2 Method()
{
base.Method();
return new MyClass2();
}
}
However since there are a lot of such methods it will be better to move the methods into the base class MyClass at all:
3.
abstract class MyClass<T>: where T : MyClass<T>
{
protected abstract T Create();
public T Method()
{
...
return Create();
}
}
class MyClass1 : MyClass<MyClass1>
{
protected override MyClass1 Create() => new MyClass1();
}
class MyClass2 : MyClass<MyClass2>
{
protected override MyClass2 Create() => new MyClass2();
}
It works fine but the contract looks too weird. Of course, I can extract something like IMyInterface and return it instead of the class. However I have to preserve the original contract because it contains specific methods as well.
Upd: So, the weird thing is in bold - class MyClass1: MyClass<MyClass1>
This is the usual so-called self-type problem (you have Method() should return the same type as the object on which it was called). Your solution #3 looks a lot like F-bounded quantification. However, this is C#, not Java, so we can do a bit better using an extension class.
You can make sure those methods only get called on subclasses of MyClass by adding a where T : MyClass bound on T.
// Put all your shared methods in generic classes in here.
public static class MyMethods
{
public static T Method<T>(this T x) where T : MyClass
{
...
}
}
Your classes don't change much, except they won't need to mention Method (or the other shared methods) at all.
public abstract class MyClass
{
...
}
public class MyClass1 : MyClass
{
...
}
public class MyClass2 : MyClass
{
...
}
Yes it looks a little bit weird to have a method which only create.
Because you have a 2 classes MyClass1 and MyClass2 which have their specific different methods and only base method is common (which you put in base class) I think you can use Abstract factory pattern.
public class ClassFactory: IClassFactory
{
public MyClass Create()
{
if (some condition)
return new MyClass1;
return new MyClass2;
}
}
class MyClass
{
protected string CommonLogic()
{
//common logic
return string;
}
}
class MyClass1 : MyClass
{
public object SpecificMethod()
{
CommonLogic();
.....
}
}
class MyClass2 : MyClass
{
public object SpecificMethod2()
{
CommonLogic();
.....
}
}
In this case you won't have duplicated code and you will have some class which one will have responsibility about creating you classes and will know when and which class return. + You will easy use it IoC here.
I hope my answer will help you.
There are some rare situations where a self-referencing type constraint may be needed, but I am not convinced that this is one of them.
It seems that you want to use the factory (Create) pattern and also have those factories return different concrete types. But at the same time you are saying that these concrete types all have something in common, specified by the base class.
The conventional approach would be to define the common features in an interface (IMyInterface as you suggested) and return that from the Create method. This would capture the polymorphic aspect of the concrete classes. Then the question is how to capture the other methods that are implemented in the concrete types. For this one can simply define additional interfaces that capture the various clusters of functionality implemented by more than one of the concrete classes.
To the extent that there are any dribs and drabs of functionality left over after you've done that, I would say handle them by casting would be the easiest -- at that point the functionality would be unique to just one of the concrete classes. If you want to fly with your eyes closed you could use the 'dynamic' type instead of casting.
Also, normally the Create method is not defined in the object instances, in other words normally objects are not their own factories. Typically they are either static or in a separate factory classes. In the current situation a bit of reflection helps deal with the fact that you have multiple derived types. There are various ways to do this besides what I show below.
So … perhaps something like this:
public interface ICommonFunctionality
{
void SomethingThatEveryoneCanDo();
// ... other common functionality
}
public interface IAdditionalFunctionality1
{
void SomethingThatAFewCanDo();
// ... other special functionality
}
public interface IAdditionalFunctionality2
{
void SomethingThatOthersCanDo();
// ... other special functionality
}
public class MyClass : ICommonFunctionality
{
static public ICommonFunctionality Create(Type derivedType)
{
if (!typeof(ICommonFunctionality).IsAssignableFrom(derivedType)) { throw new ArgumentException(); }
return derivedType.CreateInstance() as ICommonFunctionality;
}
virtual public void SomethingThatEveryoneCanDo() { /* ... */ }
}
public class MyClass1 : MyClass, IAdditionalFunctionality1
{
public void SomethingThatAFewCanDo() { /* ... */ }
}
public class MyClass2 : MyClass, IAdditionalFunctionality1, IAdditionalFunctionality2
{
public void SomethingThatAFewCanDo() { /* ... */ }
public void SomethingThatOthersCanDo() { /* ... */ }
}
public class MyClass3 : MyClass, IAdditionalFunctionality2
{
public void SomethingThatOthersCanDo() { /* ... */ }
}
public static class TypeHelpers
{
public static object CreateInstance(this Type type, bool required = true)
{
System.Reflection.ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes);
if (required && ctor == null) { throw new InvalidOperationException("Missing required constructor."); }
return ctor?.Invoke(null);
}
}
P.S. I have made the base class method virtual, this is pretty much optional depending on your situation.
I need to unit-test a virtual method defined in an abstract class. But the base class is abstract, so I can't create an instance of it. What do you recommend me to do?
This is a follow up to the following question: I am thinking about if it is possible to test via an instance of a subclass of the abstract class. Is it a good way? How can I do it?
There's no rule that says a unit test can't define its own classes. This is a fairly common practice (at least for me anyway).
Consider the structure of a standard unit test:
public void TestMethod()
{
// arrange
// act
// assert
}
That "arrange" step can include any reasonable actions (without side-effects outside of the test) which set up what you're trying to test. This can just as easily include creating an instance of a class whose sole purpose is to run the test. For example, something like this:
private class TestSubClass : YourAbstractBase { }
public void TestMethod()
{
// arrange
var testObj = new TestSubClass();
// act
var result = testObj.YourVirtualMethod();
// assert
Assert.AreEqual(123, result);
}
I'm not sure what your abstract class looks like, but if you have something like:
public abstract class SomeClass
{
public abstract bool SomeMethod();
public abstract int SomeOtherMethod();
public virtual int MethodYouWantToTest()
{
// Method body
}
}
And then, as #David suggested in the comments:
public class Test : SomeClass
{
// You don't care about this method - this is just there to make it compile
public override bool SomeMethod()
{
throw new NotImplementedException();
}
// You don't care about this method either
public override int SomeOtherMethod()
{
throw new NotImplementedException();
}
// Do nothing to MethodYouWantToTest
}
Then you just instantiate Test for your unit test:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
SomeClass test = new Test();
// Insert whatever value you expect here
Assert.AreEqual(10, test.MethodYouWantToTest());
}
}
i need to do something like this in c#. But in the Exec(object) i got a compilation error.
public class ParentClass { }
public class class1 : ParentClass
{
}
public class class2 : ParentClass
{
}
public class class3 : ParentClass
{
}
public class MasterClass
{
public void ExecutionMethod(ParentClass myObject)
{
//some code
Exec(myObject);
//some code
}
public void Exec(class1 obj)
{
//some code
}
public void Exec(class2 obj)
{
//some code
}
public void Exec(class3 obj)
{
//some code
}
}
I solved using Reflection but i think must be a better approach, somebody could give me a nice idea
As #ScottChamberlain pointed out in the comments, you don't have any methods that take an argument of type ParentClass.
Take a look at the Liskov substitution principle - if you've done your implementation properly, you can substitute an instance of, for example, class1 for an instance of ParentClass, but the converse is not true at all.
Odds are, you don't need (or want) the overloads anyway. Just have ParentClass be an abstract class with an abstract Execute method that all child classes have to implement, then you can just call Execute on the class directly without bothering with the overloads. Even better, just make ParentClass an interface. (This is sometimes called the Strategy Pattern by the way).
public interface IParent {
void Execute();
}
public class class1 : ParentClass {
//Execute method implementation
}
public class class2 : ParentClass {
// ...
}
public class class3 : ParentClass {
// ....
}
public class MasterClass
{
public void ExecutionMethod(IParent myObject)
{
//some code
myObject.Execute();
//some code
}
}
I suggest you have a look at object-oriented design patterns. Specifically, the strategy pattern for this problem. Anyway, you can implement what you want like this:
public interface IParent
{
void Exec();
}
public class Child1 : IParent
{
void Exec() { /*code*/ }
}
public class Child2 : IParent
{
void Exec() { /*code*/ }
}
public class Child3 : IParent
{
void Exec() { /*code*/ }
}
public class MasterClass
{
public void ExecutionMethod(IParent myObject)
{
//some code
myObject.Exec();
//some code
}
}
You could also use an abstract class instead of an interface, if you wanted the parent class to have some functionality for the Exec method - then the child classes would have to override the method.
You can use command pattern, with dependency injection. I kind of give you an idea below. The concrete implementation will call execute on your receiver ( you logic goes there
public interface ICommand
{
void Execute();
}
public class Command1 : ICommand
{
public void Execute()
{
throw new NotImplementedException();
}
}
public class Command2 : ICommand
{
public void Execute()
{
throw new NotImplementedException();
}
}
public class Command3 : ICommand
{
public void Execute()
{
throw new NotImplementedException();
}
}
public class CommandManager
{
//you should use DI here to inject each concerete implementation of the command
private Dictionary<string, ICommand> _commands;
public CommandManager()
{
_commands = new Dictionary<string, ICommand>();
}
public void Execute(string key)
{
_commands[key].Execute();
}
}
The error your seeing is a result of your class1,2,3 objects being cast as their parent type because of the signature of the ExecutionMethod(xxx).
And not having an overridden method of Exec that takes a type of 'ParentClass' as the argument.
Probably the simplest method is to create an interface:
IDomainObject{}.
public class ParentClass : IDomainObject { }
public void ExecutionMethod(IDomainObject myObject)
{
Exec(myObject);
}
Using the interface in this way will prevent the downcast during the method call.
You need to use an interface here
Try changing ParentClass like this:
public interface IParentClass{}
Then make each of your classes implement it, like this:
public class class1 : IParentClass
{
}
public class class2 : IParentClass
{
}
Then in your MasterClass, try this:
public void ExecutionMethod(IParentClass myObject)
{
//some code
Exec(myObject);
//some code
}
public void Exec(IParentClass obj)
{
//some code
}
And then you can pass in any of your classes that implement the IParentClassinterface.
Now as an enhancement - if you want every implementation of IParentClass to have some methods and properties that you can invoke in your Exec method, do it like so:
public interface IParentClass
{
void DoTheThing();
}
This will force you to have this method in derived classes, so for example, class1 would look like this:
public class class1 : IParentClass
{
public void DoTheThing()
{
// things get done...
}
}
public class class2 : IParentClass
{
public void DoTheThing()
{
// things get done a different way...
}
}
And now in your Exec method, you can invoke like so:
public void Exec(IParentClass obj)
{
obj.DoTheThing();
}
I've the following scenario
I've an Interface
public interface ImyInterface
{
void myInterfaceMethod(string param);
}
I've an Abstract Class
public abstract class myAbstractClass
{
public myAbstractClass()
{
//something valid for each inherited class
}
public void myAbstractMethod<T>(T param)
{
//something with T param
}
}
I've a class that inherits from myAbstractClass and implements ImyInterface
public class myClass : myAbstractClass, ImyInterface
{
public myClass():base()
{}
public void ThisMethodWillNeverCall()
{
// nothing to do
}
}
And, finally, I've a class where I'll create a ImyInterface object. At this point I would call myAbstractMethod, but...
public class myFinalClass
{
public void myFinalMethod()
{
ImyInterface myObj = _myContainer<ImyInterface>();
myObj.???
}
}
Obviously there isn't this method because it isn't declared into the interface.
My solution is the following
public interface ImyInterface
{
void myInterfaceMethod(string param);
void myFakeMethod<T>(T param);
}
public class myClass : myAbstractClass, ImyInterface
{
public myClass():base()
{}
public void ThisMethodWillNeverCall()
{
// nothing to do
}
//--- a fake method
public void myFakeMethod<T>(T param)
{
base.myAbstractMethod<T>(param);
}
}
Is there any other solution better than mine?
Thank you!
First of all, your naming convention is a mess. Read up on the guidelines that Microsoft have made.
It's also hard to tell what you are trying to achieve based on your example.
Back to your question:
You should only access an interface to work with that interface. Don't try to make any magic stuff with classes/interfaces to get them working together. That usually means that the class shouldn't try to implement the interface.
It's better that you create a new interface which have the features that you want and let your class implement both.