Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking an Apache Commons CSV CSVRecord

At some point my code needs to touch a CSVRecord and I can't figure out a way to create a mock version of it.

The class is final so it can't be mocked. The constructor is private so I can't create an instance of it. How does one approach testing code that uses the CSVRecord class?

Right now the only solution that works is parsing a test fixture to get an instance of the object. Is this my best approach?

like image 916
Martinffx Avatar asked Jan 16 '17 06:01

Martinffx


People also ask

How does Apache Commons read CSV files?

csv . It's very easy to read such CSV files with Apache Commons CSV. You just need to add a single setting called withFirstRecordAsHeader() . Apache Commons CSV uses the first record as the header record and allows you to retrieve the values using the header names.

What is Apache Commons CSV?

Using Apache Commons CSV Commons CSV reads and writes files in variations of the Comma Separated Value (CSV) format. The most common CSV formats are predefined in the CSVFormat class: Microsoft Excel.

What is junit mocking?

While doing unit testing using junit you will come across places where you want to mock classes. Mocking is done when you invoke methods of a class that has external communication like database calls or rest calls.

What is mocking Java?

Mocking is the act of removing external dependencies from a unit test in order to create a controlled environment around it. Typically, we mock all other classes that interact with the class that we want to test.


1 Answers

You can use Powermock. More info: https://github.com/powermock/powermock/wiki/mockfinal

example:

import org.apache.commons.csv.CSVRecord;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest({CSVRecord.class}) // needed to mock final classes and static methods
public class YourTestClass {
    @Test
    public void testCheckValidNum_null() {
        String columnName = "colName";
        CSVRecord record = mock(CSVRecord.class);
        String contentsOfCol = "hello";
        String result;

        when(record.get(columnName)).thenReturn(contentsOfCol);

        result = record.get(columnName);

        assertEquals(contentsOfCol, result);
    }
}

Here are my maven includes (there are newer versions of libraries, this is just what I'm using):

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>1.7.4</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito</artifactId>
    <version>1.7.4</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-all</artifactId>
    <version>1.8.5</version>
    <scope>test</scope>
</dependency>
like image 71
Creature Avatar answered Sep 19 '22 10:09

Creature