0

In a simple mvc application in spring boot , I want to do unit testing of a class of service layer called LibraryService (interface) and LibraryServiceImpl.

public interface LibraryService {

    /*
     * Returns media library object given the library object id.
     */
    public MediaLibraryDetail getLibraryById(ObjectId libraryId);
}

Below we see it's implementation

@Service
public class LibraryServiceImpl implements LibraryService {

    @Autowired
    private LibraryDAOImpl libDao;


    @Override
    public MediaLibraryDetail getLibraryById(ObjectId libraryId) {
        return libDao.getLibraryById(libraryId);
    }
}

We can see it has dependency on a class MediaLibraryDetail. Also, ObjectId is another class which is type of its parameter libraryId.

I want to do unit testing in spring boot for method getLibraryById().

Here's is my code:

@RunWith(MockitoJUnitRunner.class)
public class LibraryServiceImplTest {

    @Mock
    private LibraryDAO libDao = new LibraryDAOImpl();
    @Mock
    private ObjectId libraryId;
    @InjectMocks
    private  LibraryService libraryService =new LibraryServiceImpl();


    @Test
    public void getLibraryByIdTest(){

    MediaLibraryDetail mediaLibraryDetail =new MediaLibraryDetail();
    mediaLibraryDetail.setCollectionName("abc");

    when(libDao.getLibraryById(libraryId)).thenReturn(mediaLibraryDetail);
    assertSame(mediaLibraryDetail,libraryService.getLibraryById(libraryId));

    }
}

I am getting this error java.lang.NullPointerException on this last line assertSame(mediaLibraryDetail,libraryService.getLibraryById(libraryId));

Where am I wrong ?

3 Answers 3

2

And if you use it that way?

@Mock
private LibraryDAOImpl libDao;
@Mock
private ObjectId libraryId;
@InjectMocks
private LibraryServiceImpl libraryService;
Sign up to request clarification or add additional context in comments.

7 Comments

it fails as it cannot find bean of libraryServiceImpl. Here is the error: org.mockito.exceptions.base.MockitoException: Cannot instantiate @InjectMocks field named libraryService. You haven't provided the instance at field declaration so I tried to construct the instance.However, I failed because: the type LibraryService is an interface. Similarly for libraryDao.
with Impl it should
I read somewhere else that you normally test against an implementation because the interface doesn't deliver something to test.
@BreakingBenjamin your interface has no place to inject the mock repository, so the injection never happens and you end up with an NPE on trying to access the repository in your implementation class.
@BreakingBenjamin also, when using the Mock, Spy, etc. annotations, you hand over instantiation to the mocking framework and should NOT do it explicitly.
|
1

Expanding on KLHauser's answer, I'd replace the @InjectMocks annotation (which isn't needed) with a @Spy annotation.

That way you can check whether method on the Dao/repository actually has been called that you expected to be called:

verify(libDay).getLibraryById(libraryId);

2 Comments

You cannot replace @InjectMocks with @Spy. When I read (baeldung.com/mockito-annotations) and also try it technically , @Spy could replace @Mock because it's "somehow" more similar.
@KLHauser replace may give the wrong impression. I meant it as in replacing in the code, not functionally. InjectMocks in this code does nothing, using Spy in its stead is useful because it does have functionality.
0

Here's what you need to do:

Get Rid of @InjectMocks

1 Comment

that's only part of the problem

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.