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()
{
}
}
Related
As i searched and got few points static class is sealed and uses private constructor internally then why in my code i am not able to access the method using the class name using System?
using System;
public sealed class ClasswithPrivateCons {
private ClasswithPrivateCons() { }
public void Printname() { Console.WriteLine("Hello world"); }
}
public class Program {
public static void Main() {
ClasswithPrivateCons.Printname(); // gives error
}
}
It would be useful if you also included the error you're getting, but in this case it's obvious: Printname is not a static method, so you can't call it without an instance of ClasswithPrivateCons(). Since that constructor is private, you can't construct those objects.
Three resolution options:
Make Printname() static; then ClasswithPrivateCons.Printname() will work
Make the constructor public; then new ClasswithNoLongerPrivateCons().Printname() will work
Add a public static factory method that calls the private constructor:
public static ClasswithPrivateCons New() { return new ClassWithPrivateCons(); }
ClassWithPrivateCons.New().Printname()
Sealed class is not static. When a class is defined as a sealed class, this just means that class cannot be inherited. You must create instance of it before use. Sealed class with private constructor doesn't automatically become a static class. Static class has behaviour like sealed, but it represents separate kind of object in OOP. "Sealed" just means that class cannot be inherited, but in any case we must create an instance. At the same time, static class can't be instantiated.
Constructor of class must be public, otherwise we could not create instance. Instance constructor not only initialize new object, it also responsible for creating new objects and getting them ready to use. Constructor, unlike ordinary method, leverages inner .NET mechanisms aimed to create new instance.
public sealed class ClasswithPrivateCons
{
public ClasswithPrivateCons() { }
public void Printname() { Console.WriteLine("Hello world"); }
}
class Program
{
static void Main(string[] args)
{
ClasswithPrivateCons cl = new ClasswithPrivateCons();
cl.Printname();
}
}
Also Printname method can be declared as static. Than it may be called
ClasswithPrivateCons.Printname();
I Am getting a warning message in my class, like
Add a Protected constructor or the static keyword to the class declaration
Solution
The error is gone after I tried both the below ways,
static class without constructor
public static class Program {
}
Non static class with protected using constructor
public class Program
{
protected Program() { }
}
Question:
So What is the difference between Static Class vs Protected Constructor which is mentioned in my above solution? And which one is best to use?
A static class doesn't need an instance to access its members. A static class cannot have instance members (e.g. public int MyNumber; is not allowed on a static class because only static members are allowed on a static class). Both instance and static members are allowed on a non-static class though. A class with a protected constructor can only have an instance created by itself or something that inherits from it.
public class Program
{
protected Program()
{
// Do something.
}
public static Program Create()
{
// 100% Allowed.
return new Program();
}
public void DoSomething()
{
}
}
public static class AnotherClass
{
public static Program CreateProgram()
{
// Not allowed since Program's constructor is protected.
return new Program();
}
}
public class SubProgram : Program
{
protected SubProgram()
{
// Calls Program() then SubProgram().
}
public new static Program Create()
{
// return new Program(); // We would need to move the SubProgram class INSIDE the Program class in order for this line to work.
return new SubProgram();
}
}
Program.Create(); // Can be called since Create is public and static function.
Program.DoSomething() // Can't be called because an instance has not been instantiated.
var test = Program.Create();
test.DoSomething(); // Can be called since there is now an instance of Program (i.e. 'test').
AnotherClass.CreateProgram(); // Can't be called since Program's constructor is protected.
SubProgram.Create(); // Can be called since SubProgram inherits from Program.
As for performance, this distinction doesn't really have much to do with performance.
You probably only have static members in the class and the code analyser assumes that your intention is to not be able to create instances of the class so it is asking you to either make the class static
public static class Program {
//...static members
}
or put a protected/private constructor
public class Program {
protected Program { //OR private
}
//...static members
}
to prevent instances of that class from being initialized.
A static class is basically the same as a non-static class, but there is one difference: a static class cannot be instantiated.
Reference Static Classes and Static Class Members (C# Programming Guide)
The protected constructor means that only derived classes can call the constructor
and a private constructor wont allow any other classes to initialize the class with a private constructor
A static constructor is called when the class type is instantiated. The protected constructor is called when an instance of a class is created. The protected part means only classes that inherit the class can call it.
Static Constructor: Called once when the class type is instantiated and is used to initialize static members. Does not create an instance of the class.
Protected Constructor: A constructor that can be called only by the class or a class that inherits it.
The best practices for this is that you should have a static constructor for initializing static members and a protected constructor if you only want classes that inherit to be able to create an instance of your class. You can have both.
public class MyClass
{
static readonly long _someStaticMember;
private bool _param;
static MyClass()
{
//Do Some Logic
_someStaticMember = SomeValueCalculated;
}
protected MyClass(bool param)
{
_param = param;
}
}
public class ChildClass: MyClass
{
public ChildClass(bool param) : base(param);
}
public class NotChildClass
{
public MyClass someObject = new MyClass(true); //Will Fail
}
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());
}
}
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.
Whenever I read questions RE this, or a similar topic of static inheritance, the replies are usually that this is not supported (we know that), and the reason is given as being because this is a poor design and there's probably a better way to do it. I'd love to find a better way of doing it so am open to all suggestions - here's what I am trying to do.
I have a class which has no instance data. All the methods are static. Let's call this class BaseStatic. I now want a new static class (well several of course but lets stick to one) which inherits from this static class and adds some new static methods, let's call this SubStatic.
What I want consumers to be able to write is:
SubStatic.MethodFromSub();
and also
SubStatic.MethodFromBase();
I know I could also write:
BaseStatic.MethodFromBase()
explicitly but then consumers have to know which class implements which methods. I can't do this with inheritance because I can't inherit one static class from another. So what's a better way of doing it?
Now, I know I can have these classes as instance classes, and I can define all the methods as static - that will give me the behaviour I described above but leads to other problems, namely:
When I do this:SubStatic.MethodFromBase() the SubStatic static constructor is not called because the method is running in the parent static class (the parent's static constructor is called)
If one of the static parent methods needs to call another method which the sub class can override, I need a virtual static method in the sub class. Which I know I can't have.
So poor design apparently - can anyone help me redo it? I know I can use instance inheritance and take proper use of virtual methods (I've had it working this way) but client code then always has to create an instance (or I suppose some singleton).
This could serve your purpose, though I certainly would include some exception handling and accompany its implementation with a great deal of documentation as to why and how it works.
When the static constructor for Base is run (once) all assemblies that are currently loaded in the app domain are catalogued, selecting the types that derive from Base. Iterating over those, we run the static constructors. It is worth noting though, that this no longer guarantees the cctor for each implementation will be run exactly once, logic would have to be added to each of them to re-make that assertion. Moreover, types that are loaded after the cctor for Base has been run would not be initialized by calls to methods in Base
To simulate virtual methods, use the new keyword to hide the base method. You can call the base method by qualifying it with the declaring class's name (like in class B in the example)
using System;
using System.Linq;
using System.Runtime.CompilerServices;
namespace ConsoleApplication6
{
public class Base
{
static Base()
{
Console.WriteLine("Base cctor");
var thisType = typeof (Base);
var loadedTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes());
var derivations = loadedTypes.Where(thisType.IsAssignableFrom);
foreach(var derivation in derivations)
{
RuntimeHelpers.RunClassConstructor(derivation.TypeHandle);
}
}
public static void Foo()
{
Console.WriteLine("Bar");
}
}
public class A : Base
{
static A()
{
Console.WriteLine("A cctor");
}
}
public class B : Base
{
static B()
{
Console.WriteLine("B cctor");
}
public new static void Foo()
{
Console.WriteLine("Bar!!");
Base.Foo();
}
}
class Program
{
static void Main()
{
Console.WriteLine("A:");
A.Foo();
Console.WriteLine();
Console.WriteLine("B:");
B.Foo();
Console.WriteLine();
Console.WriteLine("Base:");
Base.Foo();
Console.ReadLine();
}
}
}
EDIT
Another option lies in the CRTP (or CRGP in the C# paradigm) or curiously recurring template (generic) parameter pattern
using System;
using System.Runtime.CompilerServices;
namespace ConsoleApplication6
{
public class Base<T>
where T : Base<T>
{
static Base()
{
RuntimeHelpers.RunClassConstructor(typeof (T).TypeHandle);
}
public static void Foo()
{
Console.WriteLine("Bar");
}
}
public class Base : Base<Base>
{
}
public class A : Base<A>
{
static A()
{
Console.WriteLine("A cctor");
}
}
public class B : Base<B>
{
static B()
{
Console.WriteLine("B cctor");
}
public new static void Foo()
{
Console.WriteLine("Bar!!");
Base<B>.Foo();
}
}
class Program
{
static void Main()
{
Console.WriteLine("A:");
A.Foo();
Console.WriteLine();
Console.WriteLine("B:");
B.Foo();
Console.WriteLine();
Console.WriteLine("Base:");
Base.Foo();
Console.ReadLine();
}
}
}
In this case, when we call a static method on A we're really calling it on Base<A> which is different than Base<B> or Base so we can actually determine how the method was called and run the appropriate cctor.
You can achieve this by using Generics. For example you can use something like that:
public class MainStatic<T> where T : MainStatic<T>
{
public static void Foo()
{
}
static MainStatic()
{
RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle);
}
}
public class SubStatic : MainStatic<SubStatic>
{
public static void Bar()
{
}
}
public class Instance
{
public void FooBar()
{
SubStatic.Foo();
SubStatic.Bar();
}
}