0

I am testing a method using JUnit API and I want to test the value of a local variable so that I get a better branch coverage. In the method under test widgets is a variable of type List and while debugging I found out that it is not null. I want to test it for Null but I am not sure how to change it's value?

Method under test:

public boolean preProcess(ServiceContext ctx) throws ProcessorException {
    logMethodStartDebug( ctx, CLASS_NAME, "preProcess(ServiceContext, Object)" );

    try {

        if( Constants.YES.equalsIgnoreCase( EISSpringUtil.getMessage( ENABLE_SELF_HEALING_FLAG ) ) ) {          
            if( AppContext.getApplicationContext().containsBean( ISO + AGGREGATOR_HEALTH_PREFIX ) ) {
                IMonitoringWidgetAggregator aggregator = (IMonitoringWidgetAggregator)AppContext.getBean( ISO + AGGREGATOR_HEALTH_PREFIX );
                List<MonitoringWidget> widgets = aggregator.aggregate();

                if( widgets != null && widgets.size() > 0 ) {               
                    for( MonitoringWidget mw : widgets ) {
                        if( mw.getStatus().equals( MonitoringStatus.FAIL ) ) {
                            ctx.addMessage( ErrorMessageUtil.generateMessage( getMessageFactory(), ErrorCodeConstants.STATUS_6000, new Object[] { ctx.getSystemName(), mw.getMonitoringCode()} ) ); 
                            return false;
                        }
                    }
                }
            }
        }

        return true;
    } finally {
        logMethodEndDebug( ctx, CLASS_NAME, "preProcess(ServiceContext, Object)" );
    }
}

JUnit test case for Positive Scenario

@Test
public void testPreProcess() throws Exception {
    AppContext.setApplicationContext( applicationContext );
    ServiceContext ctx = new ServiceContext();

    boolean b = preProcess( ctx );
    assertFalse( b );
    assertNotNull( ctx );
    assertNotNull( ctx.getMessages() );
    assertNotNull( ctx.getMessages().get( 0 ) );
    assertEquals( "code:6000", ctx.getMessages().get( 0 ) .getMessageCode() );
}

Thanks in Advance

  • 1
    I see "arrow code" here. Fix that first--it's too early to worry about the small implementation detail that "widgets" might be null. See http://blog.codinghorror.com/flattening-arrow-code/ – unigeek May 10 '16 at 16:56
  • Possible duplicate of [How to test a class that has private methods, fields or inner classes?](http://stackoverflow.com/questions/34571/how-to-test-a-class-that-has-private-methods-fields-or-inner-classes) – Raedwald May 10 '16 at 17:19

2 Answers2

0

You need to define in your AppContext for the unit tests, your testing bean:

IMonitoringWidgetAggregator aggregator = (IMonitoringWidgetAggregator)AppContext.getBean( ISO + AGGREGATOR_HEALTH_PREFIX );

You do have access to the aggregator, which mean that for example if you use a CDI/IoC compatible framework like Spring (or just plain old J2EE or even something like KumulzuEE), you can use the @ContextConfiguration and @Configuration annotations to specify where do you want your @Beans to be injected from. Therefore, you can choose to inject with a mock IMonitoringWidgetAggregator or a real instance of an implementation if you want the the whole integration to be tested.

0

A straightforward option for making the widget processing the focus of unit testing is to refactor that handling into a separate method:

public boolean preProcess(ServiceContext ctx) throws ProcessorException {
    logMethodStartDebug( ctx, CLASS_NAME, "preProcess(ServiceContext, Object)" );

    try {
        if( Constants.YES.equalsIgnoreCase( EISSpringUtil.getMessage( ENABLE_SELF_HEALING_FLAG ) ) ) {          
            if( AppContext.getApplicationContext().containsBean( ISO + AGGREGATOR_HEALTH_PREFIX ) ) {
                IMonitoringWidgetAggregator aggregator = (IMonitoringWidgetAggregator)AppContext.getBean( ISO + AGGREGATOR_HEALTH_PREFIX );
                List<MonitoringWidget> widgets = aggregator.aggregate();
                return preProcessWidgets(widgets);
            }
        }

        return true;
    } finally {
        logMethodEndDebug( ctx, CLASS_NAME, "preProcess(ServiceContext, Object)" );
    }
}

private boolean preProcessWidgets(final List<MonitoringWidget> widgets) {
    if( widgets != null && widgets.size() > 0 ) {               
        for( MonitoringWidget mw : widgets ) {
            if( mw.getStatus().equals( MonitoringStatus.FAIL ) ) {
                ctx.addMessage( ErrorMessageUtil.generateMessage( getMessageFactory(), ErrorCodeConstants.STATUS_6000, new Object[] { ctx.getSystemName(), mw.getMonitoringCode()} ) ); 
                return false;
            }
        }
    }
    return true;
}

With this structure, you may now easily write new JUnit test cases that focus on the widget processing performed within the preProcessWidgets method, such as: passing a null List, passing an empty List, and you are also free to mock the widgets parameter in whatever additional way that makes sense for your application.

Sean Mickey
  • 7,618
  • 2
  • 32
  • 58