是否可以在类中没有@RunWith(MockitoJUnitRunner)注释的情况下模拟存储库?
我有一个测试通过了,没有注释,但是失败了。没有它,我的回购测试将无法进行。这是一个陷阱22。
当我使用该批注时,我的测试中的when()方法不再具有存根行为,模拟也不执行任何操作,并且尽管设置了断点并击中了这些断点(表明行/方法正在运行),verify(。 。,times(x))语句表示模拟对象从未与该方法进行交互。我一直在努力解释为什么使用@RunWith(MockitoJUnitRunner)注释会使Mockito的最简单部分无法正常工作。
我找不到任何询问此问题的主题,但也许有人知道可以使用更好的关键字。这听起来像一个已知问题吗?
这是我的考试:
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.mockito.MockitoAnnotations.initMocks;
// toggling this below annotation is the source of grief.
//@RunWith(MockitoJUnitRunner.class)
public class LoadEditEntityChangeLogServiceImplTest {
@InjectMocks
private ServiceImpl serviceMock;
@Mock
private EditStepRepository editStepRepository;
@Mock
private EditMapper editMapper;
@Before
public void init() {
initMocks(this);
}
@Test // when the RunWith is commented out, this passes. When it is not, the test fails the verify assert.
public void mapEditEntityFromAction_Test() {
EditDTO editDTO = Mockito.mock(EditDTO.class);
when(editDTO.getSysNum()).thenReturn((long)7334);
EditEntity editEntity = new editEntity();
editEntity.setSysNum(editDTO.getSysNum());
when(editMapper.mapToEntity(eq(editDTO))).thenReturn(editEntity);
editEntity response = serviceMock.mapEditEntityFromAction(editDTO);
verify(loadEditMapper, times(1)).mapToEntity(eq(loadEventDTO));
assertEquals(loadEventDTO.getSystemNumber(), response.getSystemNumber());
}
@Test // this will fail without the @RunWith as the mocked repo will be null and throws NullPointerException when used.
public void updateConvertedEventSegment_Test() {
EditEntity editEntity = new EditEntity();
EditStepEntity editStepEntity = new EditStepEntity();
editEntity.setEditStep(editStepEntity);
doReturn(editStepEntity).when(editStepRepository).save(any());
serviceMock.updateEditStep(editEntity);
verify(editEntity, times(1)).getEditStep();
verify(editStepRepository, times(1)).save(eq(editStepEntity));
}
}
答案 0 :(得分:1)
您应该了解这位跑步者的实际行为:
基本上,它允许将模拟(由Mockito.mock(...)进行模拟准备)注入到用@Mock
注释的测试字段中。在问题中,由于您已经注释掉了跑步者,所以所有这些字段都将为空。
当您用@InjectMocks
进行注释时-它将把模拟注入到注释后引用类型的对象的字段中。
这里需要澄清的一点是:MockitoAnnotations.initMocks(this)
与“运行程序”的作用相同,因此无需同时包含两者(如果出于某种原因不能使用运行程序,则应使用initMocks
,例如是否已经有另一个跑步者必须使用)
现在,您问:
是否可以在类中没有
@RunWith(MockitoJUnitRunner)
注释的情况下模拟存储库?
答案是-是的,您可以,实际上您不必使用流道,有时更方便。
因此,假设您确实使用了该运行器,那么真正的问题是“我的存储库不起作用”到底是什么意思。这是否意味着服务中存在指向该存储库及其空值的引用?
这是否意味着存在一个存储库模拟,但是当您执行“在测试中”调用时,模拟是不同的吗?
您没有在代码中显示它,但是我假设您有这样的东西:
public class ServiceImpl {
private final EditStepRepository editStepRepository;
public ServiceImpl(EditStepRepository editStepRepository) {
this.editStepRepository = editStepRepository;
}
...
}
但是,如果是这样,一旦创建了一个模拟(确实应该在ServiceImpl
类中注入了模拟(使用调试器或其他工具进行检查),则应该在存储库中指定期望值,通常是在测试中应该是这样的代码:
Mockito.when(editStepRepository.doSomething(...)).thenReturn(...)
您没有放置任何这些行,所以它不起作用。
但是总的来说,由于这个问题包含许多不确定的技术因素,因此我只能说是推测...