-1

I have a class that looks like this:

@Service
@Transactional
public class BookServiceImpl implements BookService {
    @Autowired
    private BookRepository bookRepository;

    public void removeOne(Long id) throws DataAccessException {
        bookRepository.delete(id);
    }
}

My exception tests looks like this

@Rule
public final ExpectedException exception = ExpectedException.none();

@Test
public void removeOneThrowsNullPointerException() {
    BookService foo = new BookServiceImpl();

    exception.expect(NullPointerException.class);
    foo.removeOne(1L);
}

Now this tests passes but first why must the BookService class be instantiated and normally this test would pass if was a simple unit test because we have a book with id 1L but now its a null, I have read articles on @Rule, what is actually going on? and is this a proper test for finding exception in the method removeOne()?

Dmytro Maslenko
  • 2,247
  • 9
  • 16
valik
  • 2,014
  • 4
  • 24
  • 55

1 Answers1

1

Probably you have NullPointerException on the bookRepository in your service. By other word it is not autowired properly. Did you try to debug this test to see what exactly object is null?

There are 2 possible ways to write correct tests:

  1. For integration testing you need to care about autowire all dependencies, read about Spring and testing.
  2. For pure unit testing you need to care about mocking of all dependencies.

The usage of @Rule is correct way to test exceptional cases.

UPDATE: The simplest way to test exceptional cases for service layer is to mock your repository class to throw the DataAccessException and inject it into the service class:

@Rule
public final ExpectedException exception = ExpectedException.none();

@Test
public void removeOneThrowsDataAccessException() {
    BookRepository mockedRepository = Mock(BookRepository.class);
    when(mockedRepository.get(1L)).thenThrow(new DataAccessException());

    BookService foo = new BookServiceImpl(mockedRepository);

    exception.expect(DataAccessException.class);

    foo.removeOne(1L);
}
Dmytro Maslenko
  • 2,247
  • 9
  • 16
  • my question is not about null pointer , this occures when we dont have an empty instance or variable , but normally i was given a task to write exception test for about 10 service logic that are working correctly , so how is that i should return an exception in this test ? also i am testing the scenario where i gave a null parameter to a method – valik Feb 08 '18 at 02:27
  • The simplest way to test exceptional cases for service layer is to mock your repository class to throw the `DataAccessException` and inject it into service class. – Dmytro Maslenko Feb 08 '18 at 06:47
  • can you show a code snippet on what u mean thank you – valik Feb 08 '18 at 22:06
  • See the updated my post. – Dmytro Maslenko Feb 08 '18 at 23:06
  • could not import the Mock u used in test @Dmytro maslenko – valik Feb 13 '18 at 00:46
  • You could not import due of technical issue(s) or not allowed by manager? – Dmytro Maslenko Feb 13 '18 at 01:02
  • i have an easy mock and a mockito dependency tried to import it says cannot resolve method, and also sinice removeOne method is void it doesnt accept a thenThrow statement @Dmytro maslenko – valik Feb 13 '18 at 01:06
  • Use only one framework, say, easymock. For void methods look at this post https://stackoverflow.com/questions/27866181/how-can-i-mock-a-void-method-to-throw-an-exception. – Dmytro Maslenko Feb 13 '18 at 01:09
  • im using one but not able to perform Mock(BookRepo.class) – valik Feb 13 '18 at 01:21
  • You should understand that my code may be not compilable. I gave an idea and if something couldn't be compiled try to fix it in your project. Instead of `Mock` try `Mockito.mock()`, etc. – Dmytro Maslenko Feb 13 '18 at 01:24
  • yes you right , first i created an annonymous class for DataAccesException which i think worked fined in creating the mock but i wasnt able to pass mocked repository in to instance of service class as u did , so i didnt , i ran the test and it gave a null pointer exception – valik Feb 13 '18 at 01:38
  • BookService foo = new BookServiceImpl(mockedRepository); not able to perfrom this and this is what makes the call return an exception because we have injected an exception to it Dmytro maslenko – valik Feb 13 '18 at 01:47
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/165012/discussion-between-dmytro-maslenko-and-valik). – Dmytro Maslenko Feb 13 '18 at 02:00