简体   繁体   English

无法使用 Mockito 在 Spring 引导中模拟 AWSSecretsManager

[英]Unable to mock AWSSecretsManager in Spring boot using Mockito

I am new to Java and I have created sample class for which I need to write unit test case我是 Java 的新手,我已经创建了示例 class,我需要为其编写单元测试用例

import com.amazonaws.services.secretsmanager.AWSSecretsManager;
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder;
import com.amazonaws.services.secretsmanager.model.GetSecretValueRequest;
import com.amazonaws.services.secretsmanager.model.GetSecretValueResult;
import com.amazonaws.services.secretsmanager.model.InvalidParameterException;
import com.amazonaws.services.secretsmanager.model.ResourceNotFoundException;
import org.springframework.stereotype.Component;

@Component
public class MySecretService {

    private AWSSecretsManager client;

    public MySecretService() {
        this.client = AWSSecretsManagerClientBuilder.standard().withRegion("US-west-2").build();
    }

    public String GetMyKey(String secretId) {
        GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest();
        getSecretValueRequest.setSecretId(secretId);
        try {
            GetSecretValueResult getSecretValueResult = client.getSecretValue(getSecretValueRequest);

            return getSecretValueResult.getSecretString();
        } catch (ResourceNotFoundException resourceNotFoundException) {
            throw resourceNotFoundException;
        } catch (InvalidParameterException invalidParameterException) {
            throw invalidParameterException;
        }
        catch (Exception ex)
        {
            throw  ex;
        }
    }
}

I tried to write unit test case as below我尝试编写单元测试用例如下

import com.amazonaws.services.secretsmanager.AWSSecretsManager;
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder;
import com.amazonaws.services.secretsmanager.model.GetSecretValueRequest;
import com.amazonaws.services.secretsmanager.model.GetSecretValueResult;
import com.amazonaws.services.secretsmanager.model.ResourceNotFoundException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
class MySecretServiceTest {

    @Mock
    private AWSSecretsManager client;

    private MySecretService mySecretService;

    @BeforeEach
    void setUp() {
        this.mySecretService = new MySecretService();
    }

    @Test
    void getMyKey() {
        GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest();
        getSecretValueRequest.setSecretId("test");

        GetSecretValueResult getSecretValueResult = new GetSecretValueResult();
        getSecretValueResult.setSecretString("xyz");
        when(this.client.getSecretValue(getSecretValueRequest))
                .thenReturn( getSecretValueResult);

        assertEquals("xyz", mySecretService.GetMyKey("test"));
    }
}

However my test is getting failed where it says AWSSecretsManager is null with below error.但是,我的测试失败了,它说AWSSecretsManager是 null 并出现以下错误。

java.lang.NullPointerException at com.example.demo.MySecretServiceTest.getMyKey(MySecretServiceTest.java:40) java.lang.NullPointerException 在 com.example.demo.MySecretServiceTest.getMyKey(MySecretServiceTest.Z93F725A07423FE1C889F440B33D21F6)

I tried different solution but won't help me to execute the test cases successfully.我尝试了不同的解决方案,但无法帮助我成功执行测试用例。

I think that way how did you structure your code, you make it really hard to inject AWSSecretsManager client.我认为这样你是如何构建你的代码的,你让注入AWSSecretsManager客户端变得非常困难。 This is because it is not exposed as a dependency in the MySecretService service.这是因为它没有作为MySecretService服务中的依赖项公开。

What I suggest doing is the following:我建议做的是:

  1. Create a configuration class and put an instance for AWSSecretsManager in the IoC container:创建配置 class 并将AWSSecretsManager的实例放入 IoC 容器中:
@Configuration
public class AWSConfig {
    @Bean
    public AWSSecretsManager awsSecretsManager() {
        return AWSSecretsManagerClientBuilder.standard()
                .withRegion("us-east-1")
                .build();
    }
}
  1. Inject the bean of AWSSecretsManager inside your service:在您的服务中注入AWSSecretsManager的 bean:
@Service
public class MySecretService {
    private final AWSSecretsManager awsSecretsManager;

    public SecretsService(AWSSecretsManager awsSecretsManager) {
        this.awsSecretsManager = awsSecretsManager;
    }

    public String getMyKey(String secretId) {
        GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest().withSecretId(secretId);
        try {
            GetSecretValueResult getSecretValueResult = awsSecretsManager.getSecretValue(getSecretValueRequest);
            return getSecretValueResult.getSecretString();
        } catch (ResourceNotFoundException | InvalidParameterException resourceNotFoundException) {
            throw resourceNotFoundException;
        }
    }
}
  1. Now, in your test I see that you are mixing JUnit 4 and Junit 5 dependencies, which is not a good idea.现在,在您的测试中,我看到您正在混合 JUnit 4 和 Junit 5 依赖项,这不是一个好主意。 The latest Spring Boot starter for testing comes with JUnit 5, I suggest sticking to it.最新的 Spring 用于测试的启动启动器附带 JUnit 5,我建议坚持使用它。 Knowing this, we can do the following:知道了这一点,我们可以做以下事情:
import com.amazonaws.services.secretsmanager.AWSSecretsManager;
import com.amazonaws.services.secretsmanager.model.GetSecretValueRequest;
import com.amazonaws.services.secretsmanager.model.GetSecretValueResult;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class MySecretServiceTest {

    @Mock
    private AWSSecretsManager client;

    @InjectMocks
    private SecretsService mySecretService;

    @Test
    void getMyKey() {
        GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest();
        getSecretValueRequest.setSecretId("test");

        GetSecretValueResult getSecretValueResult = new GetSecretValueResult();
        getSecretValueResult.setSecretString("xyz");
        when(client.getSecretValue(getSecretValueRequest))
                .thenReturn(getSecretValueResult);

        assertEquals("xyz", mySecretService.GetMyKey("test"));
    }
}

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

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