Is there a JUnit equivalent to NUnit's testcase attribute?
Asked Answered
M

6

26

I've googled for JUnit test case, and it comes up with something that looks a lot more complicated to implement - where you have to create a new class that extends test case which you then call:

public class MathTest extends TestCase {
    protected double fValue1;
    protected double fValue2;

    protected void setUp() {
       fValue1= 2.0;
       fValue2= 3.0;
    }
 }

public void testAdd() {
   double result= fValue1 + fValue2;
   assertTrue(result == 5.0);
}

but what I want is something really simple, like the NUnit test cases

[TestCase(1,2)]
[TestCase(3,4)]
public void testAdd(int fValue1, int fValue2)
{
    double result= fValue1 + fValue2;
    assertIsTrue(result == 5.0);
}

Is there any way to do this in JUnit?

Macaluso answered 29/12, 2010 at 12:35 Comment(8)
JUnit has two styles: version 3, which you have in your example, and version 4, which uses annotations. Do you really want to know about version 3?Applique
Ah.. No...I want to know about 4.5...Macaluso
I think what I might be looking for is Parameterised Tests. But even this looks a bit verbose and a little bit random... mkyong.com/unittest/junit-4-tutorial-6-parameterized-testMacaluso
looks like you can only have 1 parameterised test per class. Shit or what?Macaluso
you can use kentbeck.github.com/junit/javadoc/latest/org/junit/experimental/… to put multiple test classes in one class, which would allow you to have multiple parameterized tests per class.Quevedo
@Macaluso You can have multiple test methods that take the same parameters. If you want another set of parameters, you do need a new test class.Glasswork
NUnit is derived from JUnit and now it is much advanced than JUnit. TestCase is just one of the example that makes NUnit so easy to use.Bireme
Uhhh, I answered this question 3 years ago, but just now noticed that 1 + 2 != 5, nor does 3 + 4Keyte
S
13

2017 update: JUnit 5 will include parameterized tests through the junit-jupiter-params extension. Some examples from the documentation:

Single parameter of primitive types (@ValueSource):

@ParameterizedTest
@ValueSource(strings = { "Hello", "World" })
void testWithStringParameter(String argument) {
    assertNotNull(argument);
}

Comma-separated values (@CsvSource) allows specifying multiple parameters similar to JUnitParams below:

@ParameterizedTest
@CsvSource({ "foo, 1", "bar, 2", "'baz, qux', 3" })
void testWithCsvSource(String first, int second) {
    assertNotNull(first);
    assertNotEquals(0, second);
}

Other source annotations include @EnumSource, @MethodSource, @ArgumentsSource and @CsvFileSource, see the documentation for details.


Original answer:

JUnitParams (https://github.com/Pragmatists/JUnitParams) seems like a decent alternative. It allows you to specify test parameters as strings, like this:

@RunWith(JUnitParamsRunner.class)
public class MyTestSuite {
    @Test
    @Parameters({"1,2", "3,4"})
    public testAdd(int fValue1, int fValue2) {
       ...
    }
}

You can also specify parameters through separate methods, classes or files, consult the JUnitParamsRunner api docs for details.

Sharkskin answered 10/7, 2013 at 18:24 Comment(0)
O
11

Apparently the correct answer is "No, there is no equivalent." And that's sad.

JUnit parameterized tests and theories (as mentioned here and in JUnit - How to test a method with different values?) both can get the job done, but nowhere nearly as cleanly. They are sadly complicated to write, and hard to read.

I hope that one day JUnit can add an easier, NUnit-like syntax. Seems like it shouldn't be that difficult; though perhaps lambdas are needed?

Osrick answered 8/4, 2013 at 19:42 Comment(1)
Lambdas are probably not needed as much as proper generics, but that's only a guess here. Annotations/Attributes don't depend on anonymous functions at all.Wayward
K
6

It might also be worthwhile to check out JUnit Theories and Datapoints. They let you parametrize tests, but run an all-pairs type combination on your inputs.

Keyte answered 9/9, 2012 at 7:3 Comment(1)
This looks like the answer closest to the requirements.Duckboard
R
5

You can have junit with parameters using zohhak

Usage example:

@RunWith(ZohhakRunner.class)
public class HelloWorldTest {

    @TestWith({
        "2, 1,   3",
        "3, 5,   8"
    })
    public void should_add_numbers(int addend1, int addend2, int result) {

        assertThat(addend1 + addend2).isEqualTo(result);
    }
}
Replacement answered 2/8, 2014 at 20:55 Comment(1)
This is even nicer than JUnit 5's new @ValueSource feature.Reflux
B
2

It's silly but here is the workaround that I have in the end. Use 4 lines instead one line.

@Test
public void testAdd1() {
    testAdd(1,2);
}
@Test
public void testAdd2() {
    testAdd(3,4);
}
private void testAdd(int fValue1, int fValue2)
{
    double result= fValue1 + fValue2;
    assertIsTrue(result == 5.0);
}
Bireme answered 3/6, 2012 at 21:43 Comment(1)
I like ur workaround. Today we are supposed to use @ParameterizedTest annotationLilia
L
0

I have used a holding class to hold my test cases like this:

class FlexiTest {
String var1;
String var2;
double var3;
String var4;
MyObject var5;
double expected;

public FlexiTest(String var1, String var2, double var3, String var4, MyObject var5, double expected) {
    super();
    this.var1;
    this.var2;
    this.var3;
    this.var4;
    this.var5;
    this.expected = expected;
}

Then setup a stream of my the test class objects like this:

static Stream<FlexiTest> provider(){

    FlexiTest ft1 = new FlexiTest("1", "2", 3, "4", MyObject.A, 1.1);
    FlexiTest ft2 = new FlexiTest("10", "20", 30, "40", MyObject.B, 11);
    FlexiTest ft3 = new FlexiTest("100", "200", 300, "400", MyObject.C, 110);
    
    return Stream.of(ft1, ft2, ft3);
}

Then annotated the Test method with @ParameterizedTest and @MethodSource with the stream of objects method name. Also null and empty checks:

@ParameterizedTest
@MethodSource("provider")   
@NullSource
@EmptySource
public void ClientTest(FlexiTest ft)
{
... my test code ...
}
Lilia answered 19/2, 2021 at 14:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.