使用 Mockito 模拟枚举?
Mocking an enum using Mockito?
我需要模拟以下枚举:
public enum PersonStatus
{
WORKING,
HOLIDAY,
SICK
}
这是因为我正在测试的class中使用了它:
Class 测试中:
public interface PersonRepository extends CrudRepository<Person, Integer>
{
List<Person> findByStatus(PersonStatus personStatus);
}
这是我目前的测试尝试:
当前测试:
public class PersonRepositoryTest {
private final Logger LOGGER = LoggerFactory.getLogger(PersonRepositoryTest.class);
//Mock the PersonRepository class
@Mock
private PersonRepository PersonRepository;
@Mock
private PersonStatus personStatus;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
assertThat(PersonRepository, notNullValue());
assertThat(PersonStatus, notNullValue());
}
@Test
public void testFindByStatus() throws ParseException {
List<Person> personlist = PersonRepository.findByStatus(personStatus);
assertThat(personlist, notNullValue());
}
}
给出以下错误:
错误:
org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class PersonStatus
Mockito cannot mock/spy following:
- final classes
- anonymous classes
- primitive types
我该如何解决这个问题?
您的 testFindByStatus
试图断言 findByStatus
不 return null。
如果无论 personStatus
参数的值如何,该方法都以相同的方式工作,只需传递其中之一:
@Test
public void testFindByStatus() throws ParseException {
List<Person> personlist = PersonRepository.findByStatus(WORKING);
assertThat(personlist, notNullValue());
}
如果其他可能值的行为可能不同,您可以测试每个值:
@Test
public void testFindByStatus() throws ParseException {
for (PersonStatus status : PersonStatus.values()) {
List<Person> personlist = PersonRepository.findByStatus(status);
assertThat(personlist, notNullValue());
}
}
补图:
最新版本的 Mockito 2 很好地支持对 final 的模拟 类。但是您必须首先明确启用这个新的实验性功能!
(请参阅 here 了解如何执行此操作 - 归结为将文件 mockito-extensions/org.mockito.plugins.MockMaker
添加到您的类路径,其中包含值 mock-maker-inline
)
但是当然:只有在必要时才可以嘲笑某些东西。您模拟 Enum 实例的愿望很可能是因为不理解这一点 - 或者因为您在这里创建了难以测试的代码。从这个意义上说,真正的答案是首先研究避免这种嘲笑的方法。
如前所述,使用 Mockito 2 并启用实验性功能。
实际上缺少的是一个示例片段来演示如何。
考虑到一个名为 LicenseHistoryAction
的枚举有 4 个已经存在的值,这将正确地模拟一个 UNSUPPORTED
一个:
try (MockedStatic<LicenseHistoryAction> licenseHistoryActionMockedStatic = Mockito.mockStatic(LicenseHistoryAction.class)) {
final LicenseHistoryAction UNSUPPORTED = Mockito.mock(LicenseHistoryAction.class);
Mockito.doReturn(4).when(UNSUPPORTED).ordinal();
licenseHistoryActionMockedStatic.when(LicenseHistoryAction::values)
.thenReturn(new LicenseHistoryAction[]{
LicenseHistoryAction.ASSIGN,
LicenseHistoryAction.RELEASE,
LicenseHistoryAction.UNBIND,
LicenseHistoryAction.DENY,
UNSUPPORTED});
}
我需要模拟以下枚举:
public enum PersonStatus
{
WORKING,
HOLIDAY,
SICK
}
这是因为我正在测试的class中使用了它:
Class 测试中:
public interface PersonRepository extends CrudRepository<Person, Integer>
{
List<Person> findByStatus(PersonStatus personStatus);
}
这是我目前的测试尝试:
当前测试:
public class PersonRepositoryTest {
private final Logger LOGGER = LoggerFactory.getLogger(PersonRepositoryTest.class);
//Mock the PersonRepository class
@Mock
private PersonRepository PersonRepository;
@Mock
private PersonStatus personStatus;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
assertThat(PersonRepository, notNullValue());
assertThat(PersonStatus, notNullValue());
}
@Test
public void testFindByStatus() throws ParseException {
List<Person> personlist = PersonRepository.findByStatus(personStatus);
assertThat(personlist, notNullValue());
}
}
给出以下错误:
错误:
org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class PersonStatus
Mockito cannot mock/spy following:
- final classes
- anonymous classes
- primitive types
我该如何解决这个问题?
您的 testFindByStatus
试图断言 findByStatus
不 return null。
如果无论 personStatus
参数的值如何,该方法都以相同的方式工作,只需传递其中之一:
@Test
public void testFindByStatus() throws ParseException {
List<Person> personlist = PersonRepository.findByStatus(WORKING);
assertThat(personlist, notNullValue());
}
如果其他可能值的行为可能不同,您可以测试每个值:
@Test
public void testFindByStatus() throws ParseException {
for (PersonStatus status : PersonStatus.values()) {
List<Person> personlist = PersonRepository.findByStatus(status);
assertThat(personlist, notNullValue());
}
}
补图:
最新版本的 Mockito 2 很好地支持对 final 的模拟 类。但是您必须首先明确启用这个新的实验性功能!
(请参阅 here 了解如何执行此操作 - 归结为将文件 mockito-extensions/org.mockito.plugins.MockMaker
添加到您的类路径,其中包含值 mock-maker-inline
)
但是当然:只有在必要时才可以嘲笑某些东西。您模拟 Enum 实例的愿望很可能是因为不理解这一点 - 或者因为您在这里创建了难以测试的代码。从这个意义上说,真正的答案是首先研究避免这种嘲笑的方法。
如前所述,使用 Mockito 2 并启用实验性功能。
实际上缺少的是一个示例片段来演示如何。
考虑到一个名为 LicenseHistoryAction
的枚举有 4 个已经存在的值,这将正确地模拟一个 UNSUPPORTED
一个:
try (MockedStatic<LicenseHistoryAction> licenseHistoryActionMockedStatic = Mockito.mockStatic(LicenseHistoryAction.class)) {
final LicenseHistoryAction UNSUPPORTED = Mockito.mock(LicenseHistoryAction.class);
Mockito.doReturn(4).when(UNSUPPORTED).ordinal();
licenseHistoryActionMockedStatic.when(LicenseHistoryAction::values)
.thenReturn(new LicenseHistoryAction[]{
LicenseHistoryAction.ASSIGN,
LicenseHistoryAction.RELEASE,
LicenseHistoryAction.UNBIND,
LicenseHistoryAction.DENY,
UNSUPPORTED});
}