4

I have a query about using parameterized tests for my unit testing of my APIs. Now instead of building an arraylist like

Arrays.asList(new Object[]{
   {1},{2},{3}
});

I want to read lines in the file one by one split them space and fill them in the array. This way everything would be generalized. Can anyone suggest me any such method with example?

Also is there a way that I could be testing without declaring various arguments as the private members and initializing them in the constructor of the test unit?

EDIT: Code as asked by Duncan

@RunWith(Parameterized.class)
public class JunitTest2 {

    SqlSession session;
    Integer num;
    Boolean expectedResult;
    static BufferedInputStream buffer = null;

    public JunitTest2(Integer num, Boolean expected){
        this.num = num;
        this.expectedResult = expected;
    }

    @Before
    public void setup() throws IOException{
        session = SessionUtil.getSqlSessionFactory(0).openSession();
        SessionUtil.setSqlSession(session);
        buffer = new BufferedInputStream(getClass().getResourceAsStream("input.txt"));
        System.out.println("SETUP!");
    }

    @Test
    public void test() {
        assertEquals(expectedResult, num > 0);
        System.out.println("TESTED!");
    }

    @Parameterized.Parameters
    public static Collection getNum() throws IOException{
        //I want my code to read input.txt line by line and feed the input in an arraylist so that it returns an equivalent of the code below

        return Arrays.asList(new Object[][]{
            {2, true},
            {3, true},
            {-1, false}
        });
    }
    @After
    public void tearDown() throws IOException{
        session.close();
        buffer.close();
        System.out.println("TEARDOWN!");
    }
}

Also my input.txt will be as follows:

2 true
3 true
-1 false
jcateca
  • 65
  • 5
Sourabh
  • 1,253
  • 6
  • 21
  • 39
  • So you want to have a file with the contents `1 2 3` and parse that? Can you show us what you've tried so we know where exactly you are stuck? Regarding your second question, the answer is no if you want to use parameterized tests. – Duncan Jones Jan 28 '14 at 09:28
  • For the second part, you can make public fields (no constructor needed) and annotate them with `@Parameter` (see [this sample](https://gist.github.com/Regisc/7711a96d8e99fd172a71)) –  Jan 28 '14 at 09:45
  • Kindly have a look at my code. I am a newbie to Junit so just a beginners app. – Sourabh Jan 28 '14 at 09:47
  • See https://stackoverflow.com/questions/63899534/how-to-use-junit5-parametrized-test-csv-file-source regarding the version built into JUnit5 @ParameterizedTest – Joshua Goldberg May 20 '22 at 22:26

3 Answers3

14
@RunWith(JUnitParamsRunner.class)
public class FileParamsTest {

    @Test
    @FileParameters("src/test/resources/test.csv")
    public void loadParamsFromFileWithIdentityMapper(int age, String name) {
        assertTrue(age > 0);
    }

}

JUnitParams has support for loading the data from a CSV file.

CSV File will contain

1,true
2,false
robingrindrod
  • 474
  • 4
  • 18
Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
  • I will surely try this. Looks promising and might be exactly what I need. Thanks :) – Sourabh Jan 28 '14 at 10:03
  • Yes this library is very useful, I use it a lot. It also solves some of Junit's drawbacks. A must try for data driven test. – Narendra Pathai Jan 28 '14 at 10:05
  • Great, I was looking for this for years. As we see, DataDriven tests should be very simple (technically) and can then possible be maintained in excel by the businesses / requirements / test-spec ppl. – Bastl Apr 04 '14 at 07:46
3

Have a look at the junitparams project, especially this example. It will show you how to use a CSV file for parameter input. Here's a short example:

My test.csv file:

1, one
2, two
3, three

My test:

package com.stackoverflow.sourabh.example;

import static org.junit.Assert.assertTrue;
import junitparams.FileParameters;
import junitparams.JUnitParamsRunner;

import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(JUnitParamsRunner.class)
public class FileReadingParameterizedTest {

    @Test
    @FileParameters("src/test/resources/test.csv")
    public void testWithCSV(int number, String name) {
        assertTrue(name + " is not at least two", number >= 2);
    }

}

Obviously the first test will fail, producing the error message one is not at least two.

blalasaadri
  • 5,990
  • 5
  • 38
  • 58
2

In Spring-boot Java framework, you can use the Value annotation conveniently within the class,

@Component
public class MyRunner implements CommandLineRunner {

@Value("classpath:thermopylae.txt") //Annotation
private Resource res; // res will hold that value the `txt` player

@Autowired
private CountWords countWords;

@Override
public void run(String... args) throws Exception {

    Map<String, Integer> words =  countWords.getWordsCount(res);

    for (String key : words.keySet()) {

        System.out.println(key + ": " + words.get(key));
       }
   }
}

Source

Isaac Philip
  • 498
  • 1
  • 5
  • 14