Mockito没有返回预期值

时间:2018-05-16 14:24:01

标签: java junit mockito

我正在使用 JUnit Mockito 库来测试我的应用程序。问题是,当我在代码下执行时,该值不会在运行时返回空列表并且测试失败。理想情况下,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 ????
        }
    }
}

我热切期待着支持。任何人都可以帮帮我,如何通过这个测试用例???如何通过 Mockito 将控件带到第8行以通过测试用例???

请假设,下面两个类没有真正的代码,我们只有二进制文件作为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 + "]";
    }

}

3 个答案:

答案 0 :(得分:4)

“通常”的事情:你不明白你在做什么。

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

从本质上讲,您真正的问题是您开始使用Mockito 而不了解它。低效的策略。相反,您应该从上到下阅读一个好的Mockito / Junit教程(如this一个)。要了解什么是模拟,以及你应该如何使用它们。以及如何确保测试中的代码使用模拟对象。

这里的问题是你创建的代码很难测试。鉴于您的当前设计,您必须使用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();
    ...

现在您可以使用该参数构造函数轻松地注入一个模拟工厂对象,该对象返回您需要返回的内容。

答案 1 :(得分:1)

不是调用静态工厂方法,而是注入工厂(可能在构造函数中)并在类中使用它。这样你就可以解耦类,你可以在测试阶段注入一个mock而不是一个真正的实现。 小例子:

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

答案 2 :(得分:0)

根本没有使用模拟实例。您的测试仍在使用import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; import java.io.File; import java.io.IOException; public class Main { public static void main(String[] args) { String path = args[0]; String time = args[1]; String size = args[2]; JLabel jl = new JLabel(); ImageIcon ii = null; JFrame jf = new JFrame(); jf.setDefaultCloseOperation(3); File target = new File(path); if (target.isDirectory()) { File[] files = target.listFiles(); for (File file : files) { if (is_Image(file)) { try { jl.setIcon(null); ii = new ImageIcon(ImageIO.read(file)); jl = new JLabel(ii); jl.setIcon(ii); jf.add(jl); jf.repaint(); jf.pack(); jf.setVisible(true); try { Thread.currentThread().sleep(Long.parseLong(time)); } catch (InterruptedException e) { } } catch (IOException e) { } } else { jl.setIcon(null); jl = new JLabel("Not an image"); jl.setFont(new Font("Serif", Font.PLAIN, size.charAt(0))); jl.setHorizontalAlignment(SwingConstants.CENTER); jl.setVerticalAlignment(SwingConstants.CENTER); jf.add(jl); jf.repaint(); jf.pack(); jf.setVisible(true); try { Thread.currentThread().sleep(Long.parseLong(time)); } catch (InterruptedException e) { } jl.setText(null); } } } else { try { ii = new ImageIcon(ImageIO.read(target)); } catch (IOException e) { e.printStackTrace(); } jl = new JLabel(ii); jl.setIcon(ii); jf.add(jl); jf.repaint(); jf.pack(); jf.setVisible(true); try { Thread.currentThread().sleep(Long.parseLong(time)); } catch (InterruptedException e) { } } jl = new JLabel("End of presentation"); jl.setFont(new Font("Serif", Font.PLAIN, size.charAt(0))); jl.setHorizontalAlignment(SwingConstants.CENTER); jl.setVerticalAlignment(SwingConstants.CENTER); jf.add(jl); jf.repaint(); jf.pack(); } public static boolean is_Image(File file) { try { return ImageIO.read(file) != null; } catch (Exception e) { return false; } } 类中创建的单例。

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