This question regards unit testing in Visual Studio using MSTest (this is important, because of MSTest's execution order). Both the method marked [TestInitialize] and the test class constructor will run before each test method.
So, the question is, what do you tend to do in each of these areas? Do you avoid performing certain activities in either? What is your reason: style, technical, superstition?
TestInitialize and TestCleanup are ran before and after each test, this is to ensure that no tests are coupled. If you want to run methods before and after ALL tests, decorate relevant methods with the ClassInitialize and ClassCleanup attributes.
To test that a constructor does its job (of making the class invariant true), you have to first use the constructor in creating a new object and then test that every field of the object has the correct value. Yes, you need need an assertEquals call for each field.
TestInitialize. This attribute is needed when we want to run a function before execution of a test. For example we want to run the same test 5 times and want to set some property value before running each time. In this scenario we can define one function and decorate the function with a TestInitialize attribute.
because your operation should fail if that object is null which makes sense the "behavior" fails and we should unit test that rather the actual constructors.
The constructor is just a structure provided by the language. Every test framework seems has its own controlled lifecycle "initialize". You'll probably only get into trouble using the constructor to mutate your locals.
MSTest: You get an entire new instance of the test class for every TestMethod
. This might be the only case where it's ok to mutate your locals in the constructor, initializer, or test method and not affect the other test methods.
public class TestsForWhatever
{
public TestsForWhatever()
{
// You get one of these per test method, yay!
}
[TestInitialize]
public void Initialize()
{
// and one of these too!
}
[TestMethod]
public void AssertItDoesSomething() { }
[TestMethod]
public void AssertItDoesSomethingElse() { }
}
MSpec: You only get one Establish
and Because
for all your assertions (It
). So, don't mutate your locals in your assertions. And don't depend on mutations of locals in base contexts (if you use them).
[Subject(typeof(Whatever))]
public class When_doing_whatever
{
Establish context = () =>
{
// one of these for all your Its
};
Because of = () => _subject.DoWhatever();
It should_do_something;
It should_do_something_else;
}
Here are some advantages I've found with TestInitialize.
The main advantage of using either TestInitialize() or ClassInitialize() rather than the test class instance or static constructors is its explicit nature. It clearly communicates that you are doing some setup prior to your tests. Doing this consistently should improve maintainability in the long run.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With