jav*_*999 4 java enums unit-testing final mockito
我需要模拟以下枚举:
public enum PersonStatus
{
    WORKING,
    HOLIDAY,
    SICK      
}
这是因为在我正在测试的以下类中使用了它:
被测课程:
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不会返回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的最新版本很好地支持最终类的模拟。但是,您必须首先明确启用此新实验功能!
(有关如何执行的信息,请参见此处 -它归结为将文件mockito-extensions/org.mockito.plugins.MockMaker包含值添加到类路径中mock-maker-inline)
但是,当然可以:只有必要时才嘲笑某些东西。您对Enum实例进行模拟的愿望很可能是由于不了解这一点-或因为您在此处创建了难以测试的代码。从这个意义上讲,真正的答案是首先研究避免这种嘲笑的方法。
小智 5
如前所述,使用 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});
}