简体   繁体   English

使用 Mockito 模拟枚举?

[英]Mocking an enum using Mockito?

I need to mock the following enum:我需要模拟以下枚举:

public enum PersonStatus
{
    WORKING,
    HOLIDAY,
    SICK      
}

This is because it is used in the following class that I am testing:这是因为它在我正在测试的以下类中使用:

Class under test:被测类:

public interface PersonRepository extends CrudRepository<Person, Integer>
{
    List<Person> findByStatus(PersonStatus personStatus);
}

Here is my current test attempt:这是我目前的测试尝试:

Current test:当前测试:

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());
    }
}

Which Gives following error:这给出了以下错误:

error:错误:

org.mockito.exceptions.base.MockitoException: 
Cannot mock/spy class PersonStatus
Mockito cannot mock/spy following:
  - final classes
  - anonymous classes
  - primitive types

How can I solve this?我该如何解决这个问题?

Your testFindByStatus is trying to assert that the findByStatus does not return null. 您的testFindByStatus试图断言findByStatus不返回null。

If the method works the same way regardless of the value of the personStatus param, just pass one of them: 如果方法以相同的方式工作,无论personStatus param的值如何,只需传递其中一个:

@Test
public void testFindByStatus() throws ParseException {
    List<Person> personlist = PersonRepository.findByStatus(WORKING);
    assertThat(personlist, notNullValue());
}

If the behaviour may be different for the other possible values, you can test each of them: 如果其他可能值的行为可能不同,您可以测试每个值:

@Test
public void testFindByStatus() throws ParseException {
    for (PersonStatus status : PersonStatus.values()) {
        List<Person> personlist = PersonRepository.findByStatus(status);
        assertThat(personlist, notNullValue());
    }
}

Just to complete the picture: 只是为了完成图片:

The latest version of Mockito 2 very well supports mocking of final classes. 最新版本的Mockito 2非常支持模拟最终课程。 But you have to explicitly enable this new experimental feature first! 但是你必须首先明确启用这个新的实验功能!

( see here on how to do that - it boils down to add a file mockito-extensions/org.mockito.plugins.MockMaker to your classpath, containing the value mock-maker-inline ) (请参阅此处了解如何执行此操作 - 归结为将文件mockito-extensions/org.mockito.plugins.MockMaker到类路径中,其中包含值mock-maker-inline

But of course: you only mock something if you have to. 但当然:如果必须,你只会嘲笑某事。 Your desire to mock Enum instances is most likely driven by either not understanding that - or because you created hard to test code here. 你想要模拟Enum实例的愿望很可能是由于不了解 - 或者因为你在这里创建了难以测试的代码。 In that sense the real answer would be to look into ways that avoid this kind of mocking in the first place. 从这个意义上说,真正的答案是首先考虑避免这种嘲弄的方法。

As already mentioned, using Mockito 2 and enabling experimental features.如前所述,使用 Mockito 2 并启用实验性功能。

What is actually missing, is an example snippet to demonstrate how.实际上缺少的是一个示例片段来演示如何。 Considering an enum called LicenseHistoryAction with 4 already existing values, this will properly mock an UNSUPPORTED one:考虑到一个名为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});
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM