简体   繁体   English

class 中的存根私有方法正在 junit 5 中进行测试,PowerMock 无法与 JUnit5 一起使用

[英]Stub private methods in class under test in junit 5, PowerMock not working with JUnit5

I want to stub a private method in the class under test.我想在被测 class 中存根一个私有方法。 I am using junit 5 .我正在使用junit 5 I have used before powermock to achieve this.我之前使用过powermock来实现这一点。 Unfortunately junit 5 does not work with powermock .不幸的是junit 5不适用于powermock

I have simplified the example to better explain the problem.我已经简化了示例以更好地解释问题。 I have class that has has private helper method that is called inside public methods.我有 class 具有在公共方法中调用的私有辅助方法。 Like below:如下所示:

public class Service {
    private Repository repository;

    public Object findById(String id) {
        Object object = repository.findById(id);
        object = verify(object);
        return object;
    }

    private Object verify(Object object) {
        //removed for simplicity
        return object;
    }
}

Now I want to unit test the method findById of Service .现在我想对ServicefindById方法进行单元测试。 I have used junit 5 with mockito to implement unit test for the Service class.我已经使用 junit 5 和 mockito 来实现服务 class 的单元测试。

public class ServiceUTest {
    @InjectMocks
    private Service service;
    @Mock
    private Repository repository;

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

    @Test
    public void testFindById() {
        when(repository.findById(Mockito.any())).thenReturn(new Object());
        //how to stub verify method
    }
}

I would appreciate any help and guide to solve this problem.我将不胜感激任何帮助和指导来解决这个问题。

Regards,问候,

You can spy service and use PowerMockito to define the behavior for verify() method.您可以监视服务并使用PowerMockito来定义verify()方法的行为。

public class ServiceUTest {

    @InjectMocks
    private Service service;

    @Mock
    private Repository repository;

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

    @Test
    public void testFindById() {
        // Arrange
        Service spyService = spy(service);
        when(repository.findById(Mockito.any())).thenReturn(new Object());
        PowerMockito.when(spyService, "verify", any()).thenReturn(expectedObjectReturn);

        // Act
        Object actual = spyService.findById("id");

        // Assert
    }
}

Generally, a unit test is supposed to verify the public interface of a unit.通常,单元测试应该验证单元的公共接口。

Stubbing private methods - is a bad idea.存根私有方法 - 是个坏主意。 In this case, your tests are tightly coupled to the implementation details.在这种情况下,您的测试与实现细节紧密耦合。 And usually, you want to test the behavior but not implementation.通常,您想测试行为而不是实现。

My suggestion is to return from repository such object which will comply with verification logic in a way you wanted to stub it.我的建议是从repository中返回,例如 object,它将以您想要存根的方式符合验证逻辑。

Another approach to address such issues is to move out interesting bits into a new class.解决此类问题的另一种方法是将有趣的位移到新的 class 中。 So then you can inject it as a dependency into your service.因此,您可以将其作为依赖项注入您的服务。 For example, you can use Specification pattern to extract verification logic.例如,您可以使用规范模式来提取验证逻辑。

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

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