简体   繁体   中英

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.

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.

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
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM