繁体   English   中英

Mockito没有返回期望值

[英]Mockito not returning expected value

我正在使用JUnitMockito库来测试我的应用程序。 问题是,当我在下面的代码中执行时,该值在运行时未返回空列表,并且测试失败。 理想情况下,应在执行getEmployee()时返回空列表

public class Check_Test extends TestCase
{
    public void testMyCheck()
    {
        Check checkObj = new Check();
        EmployeeFactory employeeFactoryMock = Mockito.mock(EmployeeFactory.class);
        Mockito.doReturn(Collections.EMPTY_LIST).when(employeeFactoryMock).getEmployee();
        String str = checkObj.myCheck();
        assertEquals("", str);
    }
}

我已尽我所能尝试了所有可能的方法,但是我无法通过该测试用例。

下面的Check类具有我需要测试的myCheck()方法是否为空...

public class Check
{
    public String myCheck()
    {
        List<Employee> employee = EmployeeFactory.getInstance().getEmployee();
        if (employee.isEmpty())
        {
            return ""; //Line No. 8 returning empty but, control is not coming here
        }
        else
        {
            return "NotEmpty"; // The control is always coming here ????
        }
    }
}

我热切希望得到支持。 谁能帮助我,如何通过这个测试用例???。 如何使第8行的控件通过Mockito通过测试用例???

请假设,下面的两个类没有真实的代码,我们只有二进制文件作为JAR文件,我们不能修改下面的代码...。

public class EmployeeFactory
{

    private EmployeeFactory()
    {

    }

    public static EmployeeFactory getInstance()
    {
        return EmployeeFactoryHelper.INSTANCE;

    }

    private static class EmployeeFactoryHelper
    {
        public static final EmployeeFactory INSTANCE = new EmployeeFactory();
    }

    private static List<Employee> employees = null;

    static
    {
        employees = Arrays.asList(
                                  new Employee("Manish", "Kumar", true, 60),
                                  new Employee("Siva", "Attla", true, 42),
                                  new Employee("Anand", "Manivel", false, 51),
                                  new Employee("Madhavi", "Govind", true, 45),
                                  new Employee("Janani", "Chidambaram", true, 45),
                                  new Employee("Mannu", "Krishna", false, 39),
                                  new Employee("Karthika", "Hosamane", false, 39)
                          );
    }

    public List<Employee> getEmployee()
    {
        return employees;

    }

}


public class Employee
{

    private String firstName;
    private String lastName;
    private boolean workStatus;
    private int age;

    public Employee(String firstName, String lastName, boolean workStatus, int age)
    {
        super();
        this.firstName = firstName;
        this.lastName = lastName;
        this.workStatus = workStatus;
        this.age = age;
    }

    public String getFirstName()
    {
        return firstName;
    }

    public void setFirstName(String firstName)
    {
        this.firstName = firstName;
    }

    public String getLastName()
    {
        return lastName;
    }

    public void setLastName(String lastName)
    {
        this.lastName = lastName;
    }

    public boolean isWorkStatus()
    {
        return workStatus;
    }

    public void setWorkStatus(boolean workStatus)
    {
        this.workStatus = workStatus;
    }

    public int getAge()
    {
        return age;
    }

    public void setAge(int age)
    {
        this.age = age;
    }

    @Override
    public String toString()
    {
        return "Employee [firstName=" + firstName + ", lastName=" + lastName + ", workStatus=" + workStatus + ", age=" + age + "]";
    }

}

“平常”的事情:您不了解自己在做什么。

含义:仅“创建”模拟对象是不够的。 你必须以某种方式确保相应的嘲笑对象是正在测试的代码中使用,例如通过使用@InjectMocks注解。

本质上,您真正的问题是您在不了解Mockito的情况下开始使用它。 低效的策略。 相反,您应该从上至下阅读一本不错的Mockito / Junit教程(如教程)。 了解什么是模拟,以及如何使用它们。 以及如何确保被测代码使用模拟对象。

这里的问题是您创建了不必要的难以测试的代码。 根据当前的设计,您将不得不使用PowerMock(ito)或JMockit-因为您将不得不“拦截”此调用

public static final EmployeeFactory INSTANCE = new EmployeeFactory();

您的问题是您必须控制该INSTANCE对象。 由于您无权访问该对象,因此必须拦截对new()的调用,只有PowerMock(ito)或JMockit允许您执行此操作。

因此,真正的答案是像这样改变您的设计:

public class Check { 
   private final EmployeeFactory factory;
   public Check() { this(EmployeeFactory.getInstance()); } 

   Check(EmployeeFactory factory) { this.factory = factory }

  public String myCheck() {
    List<Employee> employee = factory.getEmployee();
    ...

现在你可以使用这个参数,以构造很容易地注入了嘲笑工厂对象,返回你需要返回什么。

而不是调用静态工厂方法,而是注入工厂(可能在构造函数中)并在类中使用它。 这样,您就可以取消类的耦合,并且可以在测试阶段注入模拟而不是实际的实现。 小例子:

class EmployeeFactory{
  public Employee getEmployee(){...}
}

class Check{
  private EmployeeFactory factory;
  public Check(EmployeeFactory factory){ this.factory = factory;

  public String myCheck()
  {
    List<Employee> employee = factory.getEmployee();
}

在模拟中:

public class Check_Test extends TestCase
{
    public void testMyCheck()
    {
        EmployeeFactory employeeFactoryMock = Mockito.mock(EmployeeFactory.class);
        Check checkObj = new Check(employeeFactoryMock);
        Mockito.doReturn(Collections.EMPTY_LIST).when(employeeFactoryMock).getEmployee();
        String str = checkObj.myCheck();
        assertEquals("", str);
    }
}

完全不使用模拟实例。 您的测试仍然使用在EmployeeFactory类内部创建的单例。

为了纠正这种情况,您需要允许注入单例实例,以便它可以在测试过程中使用模拟,并在发行版本中使用实际实例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM