【问题标题】:Quarkus Junit5 mock functions from the same class来自同一类的 Quarkus Junit5 模拟函数
【发布时间】:2021-12-27 17:58:17
【问题描述】:

我正在尝试模拟一个由我尝试进行单元测试的其他函数调用的函数。我目前正在使用以下代码,遵循here 给出的建议:

@QuarkusTest
public class SampleServiceTest {
    @Inject
    SampleService sampleService;

    @Test
    public void testFindById() {
        // Given
        final Sample sample = SampleDataProvider.createSample();
        final SampleResponse expectedResponse = SampleDataProvider.createSampleResponse();
        MockedStatic<SampleResponseAssembler> mockedStatic = mockStatic(SampleResponseAssembler.class);

        // When
        doReturn(sample).when(sampleService).findSampleById(SampleDataProvider.ID);
        mockedStatic.when(() -> SampleResponseAssembler.fromSample(sample)).thenReturn(expectedResponse);
        final SampleResponse sampleResponse = sampleService.findById(SampleDataProvider.ID);

        // Then
        verify(sampleService, times(1)).findSampleById(SampleDataProvider.ID);
        mockedStatic.verify(() -> SampleResponseAssembler.fromSample(sample), times(1));
        assertEquals(expectedResponse, sampleResponse);
    }
}

正在测试的功能:

    public SampleResponse findById(final UUID id) {
        LOGGER.debug("findById. id={}", id);
        
        return SampleResponseAssembler.fromSample(findSampleById(id));
    }

    public Sample findSampleById(final UUID id) {
        LOGGER.debug("findSampleById. id={}", id);

        final Optional<Sample> optionalSample = sampleRepository.findById(id);
        return optionalSample
                .orElseThrow(() -> new NotFoundException(NotFoundException.NotFoundErrorMessage.SAMPLE_ID,
                        id.toString()));
    }

我基本上希望能够模拟 findSampleById 函数。我已经进行了此更改并且它工作正常,但“initMocks”已被弃用,因此我需要另一个解决方案:

    @Spy
    @InjectMocks
    SampleService sampleService;

    @Mock
    SampleRepository sampleRepositoryMock;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.initMocks(this);
    }

【问题讨论】:

    标签: java unit-testing testing mockito quarkus


    【解决方案1】:

    使用@ExtendWith(MockitoExtension.class) 而不是@QuarkusTest

    import org.junit.jupiter.api.BeforeEach;
    import org.junit.jupiter.api.Test;
    import org.junit.runner.RunWith;
    import org.mockito.InjectMocks;
    import org.mockito.Mock;
    import org.mockito.Spy;
    import org.mockito.runners.MockitoJUnitRunner;
    
    @ExtendWith(MockitoExtension.class)
    class SampleServiceTest {
    
        @Spy
        @InjectMocks
        SampleService sampleService;
    
        @Mock
        SampleRepository sampleRepositoryMock;
    
        @BeforeEach
        void setUp() {
            // Not needed
        }
    
        @Test
        void testFindById() {
            // ...
        }
    }
    

    另外,IMO,如果我们必须模拟 findSampleById 来测试 findById,您应该将它们分成两个类,而不是使用 @Spy。当代码难以测试时,可能需要更好地设计。

    【讨论】:

    • 我同意你的说法,但我将 findSampleById 的逻辑放在哪里?我也不认为从同一个类调用方法是不好的设计,我想这取决于在这个函数中做了什么,在这种情况下,我不认为它是另一个类的一部分:S 无论如何,我不太明白答案。除了@BeforeEach,我还应该使用最后一个 sn-p 的代码吗?以及如何使用@RunWith?是不同的依赖吗?
    • 添加了一个代码示例。 @RunWith 来自junit
    • 刚刚问过这个问题,因为我无法导入 RunWith。下周我会试一试,然后给你提个醒!谢谢! :D
    • 我做到了!您提供的代码不能 100% 工作。我不得不将@RunWith(MockitoJUnitRunner.class) 更改为@ExtendWith(MockitoExtension.class)。这是我找到解决方案的地方:stackoverflow.com/questions/40961057/…。我想说你可以用这个更正来编辑你的答案,然后我可以批准它:D
    • 已编辑。感谢您找到它。
    猜你喜欢
    • 1970-01-01
    • 2016-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多