Reputation: 59
I am trying to write unit test for my controller class. But instead of mocking EmployeeBussinessLogic
it is invoking real method call.
public class Controller {
@RequestMapping(value="/GetAllEmployeeDetails", method=RequestMethod.GET, produces="application/json")
public List<Employee> GetAllEmployeeDetails() {
EmployeeBussinessLogic empbl = new EmployeeBussinessLogic();
return empbl.GetAllEmployeeDetails();
}
following is the EmployeeBussinessLogic
class
public class EmployeeBussinessLogic {
@Autowired
EmployeeDAO employeeDAO;
public EmployeeBussinessLogic()
{
employeeDAO = new EmployeeDAOImpl();
}
public EmployeeBussinessLogic(EmployeeDAO explicityEmployeeDAO)
{
employeeDAO = explicityEmployeeDAO;
}
public List<Employee> GetAllEmployeeDetails()
{
List<Employee> EmployeeList = employeeDAO.listOfEmployees();
String text = "";
for(Employee emp : EmployeeList)
{
text = "Emp ID = " + emp.getEmployeeId() +
" Emp Age = " + emp.getEmployeeAge() +
" Emp Name = " + emp.getEmployeeName() +
" Emp Salary = " + emp.getEmployeeSalary().toString().trim() + "\n";
System.out.println(text);
}
return EmployeeList ;
}
}
Following is my controller test code
public class ControllerTestWithMockito {
@Mock
EmployeeBussinessLogic empBusLgcObj;
@Mock
EmployeeDAO mockEmployeeDAO;
@InjectMocks
@Autowired
Controller ctrlObj;
@Before
public void create()
{
MockitoAnnotations.initMocks(this);
List<Employee> empList = new ArrayList<Employee>();
empList.add(new Employee(1, "Emp1", 23, 1000));
empList.add(new Employee(2, "Emp2", 24, 2000));
Mockito.when(empBusLgcObj.GetAllEmployeeDetails()).thenReturn(empList);
}
@Test
public void getAllEmployeeDetailstest() {
final List<Employee> expectedEmpList = new ArrayList<Employee>();
expectedEmpList.add(new Employee(1, "Emp1", 23, 1000));
expectedEmpList.add(new Employee(2, "Emp2", 24, 2000));
final List<Employee> actualEmpList = ctrlObj.GetAllEmployeeDetails();
Assert.assertTrue(actualEmpList.size() == expectedEmpList.size());
Assert.assertTrue(actualEmpList.equals(expectedEmpList));
}
}
Upvotes: 2
Views: 1157
Reputation: 26512
Try changing to this:
Mockito.doReturn(empList).when(empBusLgcObj).GetAllEmployeeDetails();
That prevents calling the real method in spies
Upvotes: 1
Reputation: 311
Andreas_D is right that you should use injection instead of instantiating the object that you want to mock in the method GetAllEmployeeDetails
.
I only want to add that you should prefer constructor injection. It makes your code more flexible.
public class Controller{
private final EmployeeBussinessLogic employeeBusinessLogic;
@Autowired
public Controller(final EmployeeBussinessLogic employeeBusinessLogic){
this.employeeBusinessLogic = employeeBusinessLogic;
}
...
}
You can also choose to delegate the injection to another class. This can be usefull when the classes EmployeeBusinessLogic
and EmployeeDAO
are located in another library which your web layer uses.
@Configuration
public class SpringConfig{
@Bean
public EmployeeBusinessLogic employeeBusinessLogic{
return new EmployeeBusinessLogicImpl(new EmployeeDAOImpl());
}
}
EmployeeBusinessLogic can then be implemented without annotations in your library.
public class EmployeeBussinessLogic {
private final EmployeeDAO employeeDAO;
public EmployeeBussinessLogic(final EmployeeDAO employeeDAO)
{
this.employeeDAO = employeeDAO;
}
...
}
Upvotes: 0
Reputation: 114767
In your controller, do not create a new instance with new
. This code is untestable. Use injection instead:
public class Controller {
@Inject
private EmployeeBusinessLogic empbl;
@RequestMapping(value="/GetAllEmployeeDetails", method=RequestMethod.GET, produces="application/json")
public List<Employee> GetAllEmployeeDetails() {
return empbl.GetAllEmployeeDetails();
}
Upvotes: 1