unit test for a request class

Viewed 56

I created a class to registerRequest using this:

public class RegisterRequest {
    private ETLConfig etlConfig
    
    public void setETLConfig(ETLConfig etlConfig) {
        this.etlConfig = etlConfig;
    }
    
    protected void registerConsumer(ETLRequest req) {
        String key= req.getKey();
        String id= req.getId();
        Boolean isConfigSet = true;

        List<String> selectedItems = req.getSelectedItems();;
        selectedPillarList.addAll(selectedPillars);

        EtlRegistration reg = new EtlRegistration();
        reg.setCompanyKey(companyId);
        reg.setConfigSet(isConfigSet);
        reg.setItems(selectedItems);
        etlConfig.etlEndPoint().registerRequest(reg);
        List<String> registeredItems = etlConfig.etlEndPoint().getRegisteredItems(key);
        logger.info("registeredItems are:"+registeredItems);
    }
}

I added a config in .xml file

<bean id="registerRequest" class="com.example.tool.RegisterRequest"> 
    <property name="etlConfig" ref="etlConfig"/>
</bean>
    
<bean id="etlConfig" class="com.base.admin.api.endpoint.ETLConfig"/>

I am trying to create a junit class

@Test
public void testRegisterConsumer() throws Exception {
    RegisterRequest req= new RegisterRequest();
    ETLRequest etlReq = new ETLRequest();
    etlReq.setKey("123");
    ...
    req.registerConsumer(etlReq);
}

when I was running unit test ,I am getting

"java.lang.NullPointerException " at "etlConfig.etlEndPoint().registerRequest(reg);"

what I missed in this junit test? why it is throwing null pointer exception?

2 Answers

I am not an expert in Spring with Junit, but I'm pretty sure you have to use some annotation or configure something to tell Spring where to look your bean definitions so that it can configure your test instance correctly:

With Spring Boot:

@SpringBootTest
class MyTest {
  @Test
  void someTest() {
    ...
  }
}

Or with SpringExtension:

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = AppConfig.class)
public class MyAppTest {
  // ...
} 

Do note that I've only copied this bit of code from here:

-- Edit (and to answer comment):

Your test is not even injecting anything: you are creating RegisterRequest by yourself, without even using the container:

@Test
public void testRegisterConsumer() throws Exception {
    RegisterRequest req = new RegisterRequest();
    ...
    req.registerConsumer(etlReq);
}

Either you try using the RegisterRequest as parameter (I suppose in this case that SpringExtension supports ParameterResolver)

@Test
public void testRegisterConsumer(RegisterRequest req) throws Exception {
    ...
}

Either your use mocks or direct instance (eg: new ETLConfig() or you can try to inject it as parameter):

ETLConfig config = Mockito.mock(ETLConfig.class);
when(config.etlEndPoint()).thenReturn(...);

RegisterRequest req = new RegisterRequest();
req.setETLConfig(config);

in your test, you create your RegisterRequest with the new keyword, which means it is not handled by Spring, therefore the etlConfig is not autowired into it.

two options to solve it:

  1. Set the etlConfig on the tested class manually, with a real or mocked (preferably) etlConfig instance
  2. add a spring test configuration that will manage the beans for you and create both beans for you, and autowire it in your test class

To me it sounds like #2 is redundant for a simple unit test, I'd simply mock the etlConfig and set it on your class

Related