莫基托不返回预期值

  • 本文关键字:返回 java junit mockito
  • 更新时间 :
  • 英文 :


我正在使用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类中创建的单一实例。

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

最新更新