Reputation: 10297
The question I pose to myself (and now to the entire world, and perhaps beyond), is in my comment below:
[TestMethod()]
public void SetMessageTypeSubcodeTest()
{
int AMessageTypeSubcode;
// Should I put this class instantiation in MyTestInitialize?
MessageClass target = new MessageClass();
. . .
Should I do this:
[TestInitialize()]
public void MyTestInitialize()
{
MessageClass target = new MessageClass();
}
...or this:
[ClassInitialize()]
public void MyTestInitialize()
{
MessageClass target = new MessageClass();
}
...or neither?
And since C#/.NET is garbage collected, there's no need to free MessageClass in the TestCleanup() or ClassCleanup() method, is there?
Upvotes: 4
Views: 2009
Reputation: 28521
Neither. Avoid/minimise use of member variables in test class. Use local variables inside the test methods as much as possible. It will make each test more independent/separate/self-contained.
If you need some common initialisation code, create a helper function(s) with optional parameters, that can be called from (some) test methods and allow you to control initialisation data.
We should be able in different tests initialize system under test (SUT) with different parameters (e.g. configuration options), this is why we are using initialization in individual tests, not on class level. You shouldn’t expect that in the specific scenarios the parameters are the same, better to write the code in an extendable way, when the arrange parameters can be different.
See also Is it a good practice to share member variables among unit tests
From https://github.com/microsoft/testfx/issues/2928#issuecomment-2129763012
I always have hard time explaining to juniors the behavior of a class being instatiated for every test method. This is totally defeating the concept of a class that is storing and sharing state between methods.
Upvotes: 0
Reputation: 594
There is no real "right" answer to this question. Personally, given your code, I would not put that class instantiation into any kind of a setup method. I would keep that inside of each test, to make the test more readable and complete.
I believe that the right time to use a ClassInitialize or TestInitialize method is when you want to create a single consistent environment for all of the tests in that class to use. This is also why I don't like the "single test class per system class" approach. Each test class is a fixture that provides a consistent environment for its tests.
Over-aggressive refactoring of test code to move every "new Foo()" into the TestFixture will lead to wonderfully factored, but difficult to read unit tests. And for tests, I value readability over that level of factoring.
Upvotes: 2
Reputation: 31484
You want brand new instance of class you're testing for every single test in your set. This will prevent any possible side effects (which may happen), and as a result tests (which should be units, separated) influencing one another.
Upvotes: 4
Reputation: 4535
Unless construction of the class is expensive, do it every test. Guarantee you have a clean slate. You're right, you don't need to do any cleanup at test end either, unless the specific thing you're testing needs it (database connections closing, closing handshakes for web protocols, etc)
Upvotes: 3