Reputation: 21
I have a class that has static variables assigned during initialization. I would like to write unit tests for this class with modifying values for this static variable. Below is a simple code to explain my scenario
Class to test:
public class Hello {
private final static String HELLO_FINAL = "Hello " + HelloTo.getInstance().getHelloTo(); // I would like to modify this value between tests
public String sayHello() {
return HELLO_FINAL;
}
}
Supporting class:
public class HelloTo {
private String helloTo = "World";
private static HelloTo singleton = new HelloTo();
private HelloTo() {}
public static HelloTo getInstance() {
return singleton;
}
public void setHelloTo(String helloTo) {
this.helloTo = helloTo;
}
public String getHelloTo() {
return helloTo;
}
}
Test class:
import org.junit.Assert;
import org.junit.Test;
public class HelloTest {
@Test
public void testDefault() {
Assert.assertEquals("Hello World", new Hello().sayHello());
}
@Test
public void testDynamic() {
HelloTo.getInstance().setHelloTo("My name");
Assert.assertEquals("Hello My name", new Hello().sayHello());
}
}
Is there a way to make both tests successful. Currently I get a failure for testDymanic() saying:
org.junit.ComparisonFailure: expected:<Hello [World]> but was:<Hello [My name]>
Thanks in advance!
Upvotes: 0
Views: 2578
Reputation: 50716
HELLO_FINAL
is only initialized once per run; you can't reinitialize it within the same JVM. Is there a way to make both tests successful? Sure, there are countless ways. But that depends on what you're trying to test, which is not completely clear from your example.
Upvotes: 0
Reputation: 533530
Using a mutable singleton in a tests is an known problem. You have to reset the state of the singleton between tests, of even better, don't use a singleton in your tests.
You could do something like:
public enum HelloTo {
INSTANCE;
private String helloTo = "World";
public void reset() {
setHelloTo("World");
}
public void setHelloTo(String helloTo) {
this.helloTo = helloTo;
}
public String getHelloTo() {
return helloTo;
}
}
public class Hello {
public static String sayHello() {
// has to be dynamic as helloTo can change.
return "Hello " + HelloTo.INSTANCE.getHelloTo();
}
}
public class HelloTest {
@Before
public void setUp() {
HelloTo.INSTANCE.reset();
}
@Test
public void testDefault() {
Assert.assertEquals("Hello World", Hello.sayHello());
}
@Test
public void testDynamic() {
HelloTo.INSTANCE.setHelloTo("My name");
Assert.assertEquals("Hello My name", Hello.sayHello());
}
}
Upvotes: 2