如何使用JUnit在Spring Boot中的公共方法中模拟私有方法

时间:2018-08-01 19:09:12

标签: spring-boot junit mockito powermock powermockito

我想问几个问题并向您寻求建议:

我想测试我的公共方法(我使用Spring Boot,Mockito,JUnit):

@Service
public class MyClass{

public Long getClientId(List<String> nameSurname) throws AuthorizationException {
        Long operatorId;
        if(...){
        (... something not interesting ...)
            User user = getUserByLogin("AnthonyGates2");
            operatorId = nonNull(user) ? user.getOperatorId() : null;
        } else {
            List<User> users = getUserListByLogin("AnthinyGates");
            operatorId = isNotEmpty(users) ? return operatorId;
         return operatorId;
    }

如何测试方法getClientId

方法getUserByLogingetUserListByLogin在此类(MyClass)中是私有的,但是我必须模拟这些私有方法的结果,因为这些方法从外部服务检索数据。 这些私有方法如下:

User user = DelegateImpl.getDelegate().getUserByLogin(nameAndSurname);

DelegateImpl.getDelegate()。getUserByLogin从数据库获取数据,并且必须像下面这样模拟数据:

when(DelegateImpl.getDelegate().getUserByLogin(any())).thenReturn(user);

我如何测试我的公开课?我应该使用PowerMock / PowerMockito吗?我认为将这些方法公开是丑陋的,因为这些方法仅在MyClass中被调用。对于我的案例(Spring Boot,Mockito,JUnit),我找不到很好的Internet教程。

非常感谢您提供的所有提示!

最好的问候 马修

2 个答案:

答案 0 :(得分:1)

如果您不能对方法/类进行单元测试,则很可能意味着它做得太多。尝试将私有方法提取到单独的类。它不需要公开-您可以例如在同一程序包中将其本地打包。

稍后,在测试中,您将必须注入此类的模拟并模拟其行为。

MyClass的单​​元测试中的设置可能类似于以下内容:

AnotherClass anotherClassMock = Mockito.mock(AnotherClass.class);
MyClass myClass = new MyClass(anotherClassMock);

AnotherClass在哪里有方法getUserListByLogin和getUserByLogin。

编辑: 私有方法中的逻辑似乎已经调用了外部类。问题在于,您可以通过调用另一个类中的静态getDelegate()方法来获取对象的实例。

这是您可以做的:

  • MyClass中创建一个新字段,其类型与getDelegate()方法返回的字段相同(我不知道这是什么,我将其称为Delegate
  • 具有2个构造函数:一个默认构造函数,它将getDelegate方法的结果分配给您的新字段,另一个将Delegate实例作为参数并将其分配给您的字段的构造函数< / li>
  • 在测试中,使用第二个构造函数创建MyClass的实例并传递Delegate类的模拟

看起来不太像这样:

class MyClass() {
    private Delegate delegate;

    MyClass() {
        this.delegate = DelegateImpl.getDelegate();
    }

    MyClass(Delegate delegate) {
        this.delegate = delegate;
    }
    // ... the rest
}

答案 1 :(得分:1)

仅通过调用公共方法来测试单元。我认为您的示例是服务层中的一个类(包含业务逻辑),并且两个getUser ...方法应该在可以公开的其他类中(我认为在数据层中)。通过构造函数将该类作为依赖项注入(在服务对象中),以便在测试服务类时可以对其进行模拟。数据层类(带有getUser ...方法)也可以通过自己的单元测试进行测试。