Mockito:呼吁真正的实施

时间:2017-01-19 12:48:41

标签: java spring unit-testing mockito

我正在尝试为我的控制器类编写单元测试。但它不是模仿EmployeeBussinessLogic而是调用真正的方法调用。

public class Controller {

    @RequestMapping(value="/GetAllEmployeeDetails", method=RequestMethod.GET, produces="application/json")
    public List<Employee> GetAllEmployeeDetails() {

        EmployeeBussinessLogic empbl = new EmployeeBussinessLogic();
        return empbl.GetAllEmployeeDetails();

   }

以下是EmployeeBussinessLogic

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 ;
    }
}

以下是我的控制器测试代码

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));
    }

}

3 个答案:

答案 0 :(得分:1)

尝试更改为:

Mockito.doReturn(empList).when(empBusLgcObj).GetAllEmployeeDetails();

这阻止了在间谍中调用真实方法

答案 1 :(得分:1)

在您的控制器中,不要使用new创建新实例。这段代码是不可测试的。改为使用注射:

public class Controller {

    @Inject
    private EmployeeBusinessLogic empbl;

    @RequestMapping(value="/GetAllEmployeeDetails", method=RequestMethod.GET, produces="application/json")
    public List<Employee> GetAllEmployeeDetails() {

        return empbl.GetAllEmployeeDetails();
    }

答案 2 :(得分:0)

Andreas_D是正确的,您应该使用注入而不是在方法GetAllEmployeeDetails中实例化您想要模拟的对象。

我只想补充一点,你应该更喜欢构造函数注入。它使您的代码更加灵活。

public class Controller{

    private final EmployeeBussinessLogic  employeeBusinessLogic;

    @Autowired
    public Controller(final EmployeeBussinessLogic  employeeBusinessLogic){
        this.employeeBusinessLogic = employeeBusinessLogic;
    }

    ...

}

您还可以选择将注射委托给另一个类。当类EmployeeBusinessLogicEmployeeDAO位于您的网络层使用的另一个库中时,此功能非常有用。

@Configuration
public class SpringConfig{


    @Bean
    public EmployeeBusinessLogic employeeBusinessLogic{
        return new EmployeeBusinessLogicImpl(new EmployeeDAOImpl());
    }

} 

然后可以在您的库中无需注释的情况下实现EmployeeBusinessLogic。

public class EmployeeBussinessLogic {

    private final EmployeeDAO employeeDAO;

    public EmployeeBussinessLogic(final EmployeeDAO employeeDAO)
    {
         this.employeeDAO = employeeDAO;
    }

    ...
}