Sam
Sam

Reputation: 513

JUnit and Mockito returns null while mocking

I'm completely new to JUnit and Mockito. I'm facing problem while testing my ServiceImpl class. When the pointer goes inside the ServiceImpl class while debugging, the method throws nullPointerException. Could anyone please tell me how to invoke the method inside "getDetails" method. "varNumber" always returns null.

DetailsUtilsClientImpl class

  private final DetailsUtils detailsUtils;

  @Autowired
  Utils utils

 @Autowired
 public DetailsUtilsClientImpl( DetailsUtils 
 detailsUtils) {
    this.detailsUtils= detailsUtils;
}

    public Details getDetails( String var1 ) {
       String varNumber = utils.smgContent( var1 ); 
       Details getDetailsDocument =
       detailsRepository.findById( varNumber ).orElse( null );
    return null;
}

Test class

@Autowired
DetailsUtils detailsUtils;

@Autowired
DetailsUtilsClient detailsUtilsClient;

@Autowired
Utils utils

@Autowired
Pageable pageable;

 @Before
public void setUp() {
    detailsUtils = mock( DetailsUtils.class );
    utils = mock( Utils.class );
    pageable = mock( Pageable.class );
}

@Test
public void getCarDocument() {

    List<Entity.Type> listPre = new ArrayList<Entity.Type>();
    Entity.Type preTest = new Entity.Type();
    preTest.setDesc( Mob.AUTOMOB );
    preTest.setDet( Car.CAR );
    listPre.add( preTest );

    Entity c1 = new Entity();
    c1.setId( "accountID" );
    c1.setCarNo( "gfsd2134gh" );
    c1.setCarDetail( "accountDet" );
    c1.setEntity( listPre );

    detailsUtilsClient client =
        new DetailsUtilsClientImpl( detailsUtils );


    Optional<Entity> client1 = Optional.of( c1 );
    when( detailsUtils.findById( c1.getCarNo() ) ).thenReturn( client1 );
    Entity c2 = client.getEntity ( "gfsd2134gh" );
    assertThat( c2.getCarNo(), equalTo( c1.getCarNo() ) );
   }

Upvotes: 0

Views: 5732

Answers (2)

Mark Bramnik
Mark Bramnik

Reputation: 42441

Usually NPEs happen due to a wrong configuration of the test case, and you've omitted the most "meaningful" part - a test case configuration:

If you use @Autowired, the chances are that you try to use spring (otherwise it doesn't make sense). But in this case, the test should be run with a special spring runner that will start the application context, init all the beans and then autowire them to the test fields.

At least it should be @RunWith(SpringRunner.class)

In this case it's not a unit-test anymore, but more like an integration/component test.

Alternatively, if you don't want to use Spring at all, then someone has to instantiate the classes. This is a regular unit test.

JUnit as a tool by default can't instantiate anything.

So, you have to "instruct" JUnit about this. Since you're using Mockito here, probably you should use a rule or runner (instruct about junit - mockito integration):

Rule approach:

 class ExampleTest {
   @Rule
   public MockitoRule rule = MockitoJUnit.rule();
 }

Runner approach:

 @RunWith(MockitoJUnitRunner.class)
 public class ExampleTest {
 }

Upvotes: 1

Gaurav Srivastav
Gaurav Srivastav

Reputation: 2551

Never use @Autowired for dependency rather use @Mock for the dependency to mock. @InjectMocks will create object and inject all the mocked dependencies. In Unit testing, we are basically concern about the working of a method and interaction between the dependency. http://www.startwithjava.com/best-practices-for-unit-testing/

public class Test{

    @Mock
    DetailsUtils detailsUtils;

    @InjectMocks
    DetailsUtilsClient detailsUtilsClient;

    @Mock
    Utils utils;

    @Mock
    Pageable pageable;


     @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void getCarDocument() {
        //GIven
        List<Entity.Type> listPre = new ArrayList<Entity.Type>();
        Entity.Type preTest = new Entity.Type();
        preTest.setDesc( Mob.AUTOMOB );
        preTest.setDet( Car.CAR );
        listPre.add( preTest );

        Entity c1 = new Entity();
        c1.setId( "accountID" );
        c1.setCarNo( "gfsd2134gh" );
        c1.setCarDetail( "accountDet" );
        c1.setEntity( listPre );


        Optional<Entity> client1 = Optional.of( c1 );
        when( detailsUtils.findById( c1.getCarNo() ) ).thenReturn( client1 );

        //When
        Entity c2 = detailsUtilsClient.getEntity ( "gfsd2134gh" );

        //Then
        assertThat( c2.getCarNo(), equalTo( c1.getCarNo() ) );
        //use behavior test using Mockito.verify(dependency,times(noOfInteraction)).methodName(arg)
        Mockit.verify(detailsUtils,Mockito.times(1))..findById( c1.getCarNo() );
       }

    }

Upvotes: 3

Related Questions