Reputation: 19
I'm working on setting up jUnit tests with Mockito for a project. I'm having trouble when calling a method in the System Under Test (DrawingService). Mocks include a Drawing and an IDrawingRepository.
I'm new to TDD, unit testing, and mocking in general, so maybe I'm making some noob mistake? Any help would be greatly appreciated.
Here's the test class:
public class DrawingServiceTest {
private DrawingService drawingService;
private Drawing drawing;
private IDrawingRepository repository;
private String drawingName;
@Before // Executed before each @Test
public void setUp(){
drawingService = new DrawingService();
drawing = mock(Drawing.class);
repository = mock(IDrawingRepository.class);
}
@After // Executed after each @Test
public void tearDown(){
//clean up code
}
@Test
public void getDrawingTest() throws DrawingNotFoundException{
drawingName = "A drawing name that exists";
System.out.println("drawing name is: " + drawingName);
when(repository.findByName(drawingName)).thenReturn(drawing);
System.out.println("calling DrawingService.getDrawing(" + drawingName +")");
drawingService.getDrawing(drawingName); // The test doesn't continue past this line
System.out.println("verifying repository.findByName(" + drawingName +") is called");
verify(repository).findByName(drawingName);
}
Here's the System Under Test:
@Service ("iDrawingService")
public class DrawingService implements IDrawingService {
@Autowired
private IDrawingRepository repository;
public List<Drawing> getDrawings() {
return (List<Drawing>) repository.findAll();
}
public Drawing getDrawing(String strName) throws DrawingNotFoundException{
Drawing drawing = repository.findByName(strName); //this line throws the NullPointerException
if(drawing == null){
throw new DrawingNotFoundException("No drawing found for name " + strName);
}
return drawing;
}
}
Upvotes: 1
Views: 2508
Reputation: 994
Instead of using @before
and @After
in your test, you can simply annotate your subject with @InjectMocks
and all of your mocked objects with @Mock
.
With @InjectMocks
you don't even need getters and setters on the subject. In your tests you never tie repository
to the subject.
@RunWith(MockitoJUnitRunner.class)
public class DrawingServiceTest {
@InjectMocks private DrawingService drawingService;
@Mock private Drawing drawing;
@Mock private IDrawingRepository repository;
private String drawingName;
Upvotes: 0
Reputation: 727
In prod, your class will have IDrawingRepository wired by spring. This is not the case with your test (unit test). You will need to hook it up manually. Your options are:
I personally would go with constructor injection, as it is required by your class to work properly. Your class can be tested easily too.
Upvotes: 4