我正在尝试使用Mockito Framework 1.9.5和JUnit 4.11模拟我的GenericDao对象,但Mockito总是模拟第一个与该类型匹配的字段。同样符合名称也无济于事。
与API(http://docs.mockito.googlecode.com/hg-history/58d750bb5b94b6e5a554190315811f746b67f578/1.9.5/org/mockito/InjectMocks.html)中描述的一样,Mockito应该评估要模拟的正确字段。
预期输出:
EmployeeService.absenceDao -> null
EmployeeService.creditDao -> null
EmployeeService.employeeDao -> Mocked object
有效输出:
EmployeeService.absenceDao -> Mocked object
EmployeeService.creditDao -> null
EmployeeService.employeeDao -> nulll
重现这种情况的代码:
@RunWith(MockitoJUnitRunner.class)
public class EmployeeServiceTest {
@InjectMocks
EmployeeService employeeService;
@Mock(name = "employeeDao")
GenericDao<Employee> employeeDao;
@Test
public void testFindEmployeeByUsername() {
// some tests
}
}
我的模拟类,包含几个GenericDao字段,但我只是想模仿employeeDao
:
@Service
@Transactional
public class EmployeeService {
@Autowired
private GenericDao<Employee> employeeDao;
@Autowired
private GenericDao<Credit> creditDao;
@Autowired
private GenericDao<Absence> absenceDao;
答案 0 :(得分:5)
根据我调试的内容,看起来Mockito无法通过注释处理类型参数。如果您遵循MockitoJunitRunner
的堆栈跟踪,那么您最终会进入下面的DefaultAnnotationEngine
是您想要查看的方法。
public void process(Class<?> clazz, Object testInstance) {
Field[] fields = clazz.getDeclaredFields(); //This is the line of concern
for (Field field : fields) {
boolean alreadyAssigned = false;
for(Annotation annotation : field.getAnnotations()) {
Object mock = createMockFor(annotation, field);
if (mock != null) {
throwIfAlreadyAssigned(field, alreadyAssigned);
alreadyAssigned = true;
try {
new FieldSetter(testInstance, field).set(mock);
} catch (Exception e) {
throw new MockitoException("Problems setting field " + field.getName() + " annotated with "
+ annotation, e);
}
}
}
}
我评论的这一行会在没有type参数的情况下拉回你的GenericDao。那么当它注入它时。现在它真的不重要因为你通常会嘲笑那个对象来控制返回的东西。但是在你的情况下,你有3个dao&#39; s意味着当你打电话给你的employeeDao并且模拟器在AbsenceDao上时它会抛出NullPointerException
。我确实做了尝试:)。但如果你嘲笑这三个人。它过去了。现在我担心它实际上调用了正确的方法,所以我写了一些验证案例以确保。以下是我的所作所为。
GenericDAO
public interface GenericDao<T>
{
public T getObject();
}
的EmployeeService
@Service
@Transactional
public class EmployeeService
{
@Autowired
private GenericDao<Absence> absenceDao;
@Autowired
private GenericDao<Credit> creditDao;
@Autowired
private GenericDao<Employee> employeeDao;
public Absence getAbsenceObject()
{
return absenceDao.getObject();
}
public Credit getCreditObject()
{
return creditDao.getObject();
}
public Employee getEmployeeObject()
{
return employeeDao.getObject();
}
}
EmployeeServiceTest
@RunWith(MockitoJUnitRunner.class)
public class EmployeeServiceTest
{
@Mock
private GenericDao<Absence> absenceDao;
@Mock
private GenericDao<Credit> creditDao;
@Mock
private GenericDao<Employee> employeeDao;
@InjectMocks
private EmployeeService employeeService;
@Test
public void testGetObject()
{
Mockito.when(absenceDao.getObject()).thenReturn(new Absence());
Mockito.when(creditDao.getObject()).thenReturn(new Credit());
Mockito.when(employeeDao.getObject()).thenReturn(new Employee());
Assert.assertNotNull(employeeService.getEmployeeObject());
Mockito.verify(absenceDao, Mockito.never()).getObject();
Mockito.verify(creditDao, Mockito.never()).getObject();
Mockito.verify(employeeDao, Mockito.times(1)).getObject();
}
}
我希望这会有所帮助。布拉沃我也学会了回答这个问题。