Rhs
Rhs

Reputation: 3318

JUnit: Calling @After to set object to Null

Assume I have the following simple JUnit test

private Person person;

@Before
public void createObject()
{
   String firstName = "John";
   String lastName = "Doe";

   person = new Person(firstName, lastName);
}

@Test
public void test1()
{
   assert(firstName.equals("John"));
}

@Test
public void test2()
{
   assert(lastName.equals("Doe"));
}

Should I have an @After method that sets person = null?

I tried a similar test without the @After method and I can't seem to figure out it putting it in there has any advantages or disadvantages.

Ignore that the test names aren't very meaningful. I was just posting a simple example.

Upvotes: 4

Views: 1096

Answers (4)

edouglass
edouglass

Reputation: 21

No, there is no need to have a tear down method that runs after your tests in this case. In JUnit, each test method is instantiated separately, and after a test is run, your Person field will just get garbage collected. Now, if you were touching some kind external resource, say through a stream or something, you would want to make sure and close that either at the end of your test or in a tear down method.

Upvotes: 2

JB Nizet
JB Nizet

Reputation: 691755

No, that's useless. Once the test is done, the test class instance goes out of scope, and becomes eligible to GC. Your test, and its person, will thus be garbage collected if the VM decides so.

You typically use @After like you would use a finally block: to close resources that need to be closed whatever the result of a test method.

Upvotes: 5

Jeroen Vannevel
Jeroen Vannevel

Reputation: 44439

No, you don't have to since [see @JBNizet's answer].

That being said: using these types of constructors and destructors (the conceptual kind, not the language-provided kind) are prone to problems because of exactly this issue: you have to remember each object's state and how it affects the global state of your application.

An alternative I prefer is to use a simple factory method which returns that object:

private Person getPerson(){
    return new Person("John", "Doe");
}

Now you can use this in each of your tests and you won't rely on any state anymore.

@Test
public void test1()
{
   Person person = getPerson();
   assert(person.getFirstName().equals("John"));
}

Upvotes: 1

Alexey Malev
Alexey Malev

Reputation: 6533

You can, but it makes no sense. @Before method is invoked before every test run. Person will be GCed with and without @After.

Upvotes: 5

Related Questions