2
votes

I am completely stumped. I am new to Spring Batch testing and I have found countless examples that have left me confused.

I'm trying to test a Spring Batch decider. This decider checks to see if certain JSON files exist before continuing.

To begin, I have a BatchConfiguration file marked with @Configuration in my Spring Batch project.

In the BatchConfiguration, I have a ImportJsonSettings bean which loads its properties from settings in the application.properties file.

  @ConfigurationProperties(prefix="jsonfile")
    @Bean
    public ImportJSONSettings importJSONSettings(){
        return new ImportJSONSettings();
    }

When running the Spring Batch application, this works perfectly.

Next, here are the basics of the JsonFilesExistDecider , which Autowires a FileRetriever object...

public class JsonFilesExistDecider implements JobExecutionDecider {

    @Autowired
    FileRetriever fileRetriever;

    @Override
    public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) { ... }

The FileRetriever object itself Autowires the ImportJSONSettings object.

Here is the FileRetriever...

@Component("fileRetriever")
public class FileRetriever {

    @Autowired
    private ImportJSONSettings importJSONSettings;

    private File fieldsFile = null;

    public File getFieldsJsonFile(){
        if(this.fieldsFile == null) {
            this.fieldsFile = new File(this.importJSONSettings.getFieldsFile());
        }
        return this.fieldsFile;
    }
}

Now for the test file. I am using Mockito for testing.

public class JsonFilesExistDeciderTest {
    @Mock
    FileRetriever fileRetriever;
    @InjectMocks
    JsonFilesExistDecider jsonFilesExistDecider;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }
    @Test
    public void testDecide() throws Exception {
        when(fileRetriever.getFieldsJsonFile()).thenReturn(new File(getClass().getResource("/com/files/json/fields.json").getFile()));

        // call decide()... then Assert...
    }
}

PROBLEM... The ImportJSONSettings object that is @Autowired in the FileRetriever object is always NULL.

When calling the testDecide() method, I get a NPE since calling the getFieldsJsonFile() in FileRetriever, the ImportJSONSettings bean does not exist.

How does the ImportJSONSettings bean get properly created in the FileRetriever object so it can be used??

I have tried adding the following to my test class, but it does not help.

@Mock
ImportJSONSettings importJSONSettings;

Do I need to create it independently? How does it get injected into the FileRetriever?

Any help would be appreciated.

1
Is your test run with SpringRunner? Do you have a test application context so that those bean get properly injected? If it's not the case you need to do it manually. - Mahmoud Ben Hassine

1 Answers

1
votes

Try changing the @Before annotation on the setup() method to @BeforeEach like so:

@BeforeEach
void setup() {
    MockitoAnnotations.initMocks(this);
}

This could also be a dependency issue. Make sure you have a recent version of io.micrometer:micrometer-core. Would you be able to share your test dependencies?

If you have the above setup correctly, you shouldn't have to worry about whether or not ImportJSONSettings is null or not as long as you have getFieldsJsonFile() stubbed correctly.