簡體   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