Marco99
Marco99

Reputation: 1659

Mock objects and assign them to instance and static variables in a method

I have a class like this:

// This class will process the incoming flat files from various data sources
public class FileProcessor {

    private String fileName;//Say filetype_datasource_yyyyMMddHHmmss.dat
    private String fileType;
    private String fileNameWithoutExtension;
    private String fileSource;
    private String timestamp;
    private boolean validFileName;
    private static final Logger logger = Logger.getLogger(FileProcessor.class);

    public FileProcessor(String fileName) {
        this.fileName = fileName;
    }

    public void validateFileName() {
        fileNameWithoutExtension = fileName.substring(0, fileName.indexOf("."));
        String[] fileNameSplit = fileName.split("_");
        fileType = fileNameSplit[0];
        logger.info("File type: " + fileType);
        fileSource = fileNameSplit[1];
        logger.info("File source: " + fileSource);
        timestamp = fileNameSplit[2];
        logger.info("File timestamp: " + timestamp);
        validFileName = validateFileType() &&  validateFileSource() && validateTimestamp();
    }

    private boolean validateFileType() {
        boolean result;
        //Validate as per business rules
        ...
        return result;
    }

    private boolean validateFileSource() {
        boolean result;
        //Validate as per business rules
        ...
        return result;
    }

    private boolean validateTimestamp() {
        boolean result;
        //Validate as per business rules
        ...
        return result;
    }
}

The catch here is that validateFileName() uses some instance variables (fileNameWithoutExtension, fileType, fileSource, timestamp, validFileName), and a static variable (logger).

What is the best way to write JUnit test case mocking the objects that are assigned to the instance and static variables used in the method validateFileName()?

I am a beginner to Junit and object mocking, and am open to use any of the mocking frameworks that addresses the concern. Thanks.

Upvotes: 0

Views: 459

Answers (2)

Jonathan
Jonathan

Reputation: 792

You don't need to mock fields as they are all derived from fileName, which comes from constructor's argument.

So using JUnit 4 – and assuming you don't need to check what is logged, you could simply do:

import org.junit.Assert;
import org.junit.Test;

// ... other imports

public class FileProcessorTest {

    @Test
    public void test() {
        // test a valid case
        String file = "filetype_datasource_yyyyMMddHHmmss.dat";
        FileProcessor processor = new FileProcessor(file);
        Assert.assertTrue(processor.validateFileType());
        // ... more assertions

        // test where it should fail
        file = "filetype_invalid_xxx.dat";
        processor = new FileProcessor(file);
        Assert.assertFalse(processor.validateFileType());
        // ... more assertions
    }
}

Upvotes: 1

davidxxx
davidxxx

Reputation: 131556

All these variables :

 fileNameWithoutExtension, fileType, fileSource, timestamp,
 validFileName

are derived data.
You get them from the single dependency of the FileProcessor constructor : String fileName parameter.

But even String fileName should not mocked. It is not a dependency that you want to isolate. You want that it is a real/normal object as it makes part of the input data of your component.

Upvotes: 1

Related Questions