Reputation: 340
I am creating unit tests with JUnit for methods that manipulate JSON objects. I want to create a method in my test file that sets up the object that will be used in some, but not all, of my test methods. How do I selectively run the set-up method and transfer it's resulting JSONObject to the test methods? Is there a better way to do this? Here is what I was thinking for a set up method (using gson):
public static JsonObject prepareTestJson(){
JsonObject testJson_container = new JsonObject();
JsonObject testJson_inner = new JsonObject();
String ContactInfo = "+1 111 111 1111";
testJson_inner.addProperty("Contact", ContactInfo);
testJson_container.add("ID", testJson_inner);
return testJson_container;
}
Upvotes: 1
Views: 7249
Reputation: 131526
How do I selectively run the set-up method and transfer it's resulting JSONObject to the test methods?
No you cannot select the test methods for which a method annotated with @Before
should be applied.
Is there a better way to do this?
You could simply invoke this method before each test (you can also make it private
and an instance method to reduce its access :
private JsonObject prepareTestJson(){
JsonObject testJson_container = new JsonObject();
JsonObject testJson_inner = new JsonObject();
String ContactInfo = "+1 111 111 1111";
testJson_inner.addProperty("Contact", ContactInfo);
testJson_container.add("ID", testJson_inner);
return testJson_container;
}
such as :
@Test
public void foo(){
JsonObject json = prepareTestJson();
...
}
Another alternative is splitting your test class in two : one with the tests that require the setup()
and another one with the tests that don't require it.
In this way you could use a init method with @Before
or simply put these statements in the class constructor.
For example :
private JsonObject testJson_container;
@Before
public void prepareTestJson(){
testJson_container = new JsonObject();
JsonObject testJson_inner = new JsonObject();
String ContactInfo = "+1 111 111 1111";
testJson_inner.addProperty("Contact", ContactInfo);
testJson_container.add("ID", testJson_inner);
}
But this way is an artificial/technical split, it may make the test code less readable.
So I think that in most of cases, I would stick to the first way.
Additionally, with JUnit 5 you have an interesting workaround : using
@MethodSource
that is documented as :
an ArgumentsSource which provides access to values returned by methods of the class in which this annotation is declared.
This is designed to be used with @ParameterizedTest
but it may fit to your case.
You could write :
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
public class FooTest {
@ParameterizedTest
@MethodSource("prepareTestJson")
void add(JsonObject testJson_container) {
// do your logic
}
private static Arguments prepareTestJson() {
JsonObject testJson_container = new JsonObject();
JsonObject testJson_inner = new JsonObject();
String ContactInfo = "+1 111 111 1111";
testJson_inner.addProperty("Contact", ContactInfo);
testJson_container.add("ID", testJson_inner);
return Arguments.of(testJson_container);
}
}
Upvotes: 3