Reputation: 2037
I am very new to JUnit theories. I have a method parse() that takes a html String as an input and returns a Document (DOM of the HTML Document)
public Document parse(final String inputString) throws IllegalArgumentException {
if (StringUtil.isBlank(inputString))
throw new IllegalArgumentException("Input HTML String is empty,blank or null");
return Jsoup.parse(inputString, "", Parser.xmlParser());
}
I wanted to write unit tests for this using Junit theories. The boundary cases that I want to check are:
In case of first 3, it should throw an IllegalArgumentException. In case of the last 2, it returns a valid Document Object. I have been able to write the test for the first 2. But I am not sure how to test the last 3 using Junit Theories.
Here's what I have so far:
@Rule
public ExpectedException thrown = ExpectedException.none();
@DataPoints
public static String[] function(){
return new String[]{
""," ",null
};
}
@Theory
public void test(String s) {
System.out.println("called");
if(s==null)
System.out.println("null");
System.out.println(s.length());
thrown.expect(IllegalArgumentException.class);
htmlAssessment.parse(s);
}
For some reason, the test method isnt called for the argument String = null. Could someone help me with testing the last 3 cases?
Console o/p:
called
0
called
1
Upvotes: 3
Views: 1712
Reputation: 56694
Just try to upgrade your JUnit to release 4.12.
The problem was fixed.
See the below URLs for many details:
Up until JUnit 4.11 a @DataPoints-annotated array field could contain null values, but the array returned by a @DataPoints-annotated method could not. This asymmetry has been resolved: both can now provide a null data point.
Upvotes: 0
Reputation: 32969
So I believe this post answers the question about using null
in @DataPoints
. JUnit 4.12 issue when using theory + enum type + DataPoint that contains a null.
It appears that @DataPoints
does not use the type of the declared field to determine the type of the Theory
input. Instead it analyzes each actual value. Because of this null
is not being linked to String
but to Object
. And the premise is that null
should not be provided to every argument in a Theory
.
Hence, it appears that you cannot use null
in @DataPoints
. As has been pointed out, you would need to use @DataPoint
. However, rather than having 3 @DataPoint
values you could do the following...
@DataPoints
public static String[] nonNullValues = new String[]{"", " "};
@DataPoint
public static String nullValue = null;
However, I do have another solution. Recently I discovered @TestedOn. This allows for the following:
@Theory
public void testIt(@TestedOn(ints={3,4,5}) int value){...}
Unfortunately @TestedOn
was only implemented for int
. I implemented my own @TestOn that allows for all the primitive types. So your test could successfully be written as:
@Theory
public void testIt(@TestOn(strings={"", " ", TestOn.NULL}) String value){...}
This will correctly test on null
. I have really liked this mechanism because it allows me to map Theory
values to individual tests.
Upvotes: 4
Reputation: 1575
When you use @DataPoint instead of @DataPoints and individually assigns the three combinations to different Strings it works and it calls the test() method even when the String is null.
@DataPoint public static String input1 = "";
@DataPoint public static String input2 = " ";
@DataPoint public static String input3 = null;
PS: @Nemin found the answer to his own question. Just wanted to leave it here so it's easier to find.
PS2: If you know if this is a bug or a feature of JUnit, or if there's another way to solve it keeping @DataPoints, please do share this information here.
Upvotes: 1