使用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

我该如何解决这个问题?

只需完成图片:

Mockito 2的最新版本非常支持对最终类的嘲讽。但您必须首先明确启用这个新的实验功能!

(请参阅此处关于如何做到这一点的内容——它可以归结为向类路径中添加一个文件mockito-extensions/org.mockito.plugins.MockMaker,其中包含值mock-maker-inline

但当然:只有在必要的情况下,你才能模拟某些东西。你想要模拟Enum实例很可能是因为你不理解这一点,或者因为你在这里创建了难以测试的代码。从这个意义上说,真正的答案是从一开始就寻找避免这种嘲笑的方法。

您的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并启用实验功能。

实际上缺少的是一个示例片段来演示如何操作。考虑到一个名为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});
}

最新更新