gpt4 book ai didi

junit - 在 Spring 中模拟 RestTemplate

转载 作者:行者123 更新时间:2023-12-04 14:38:05 24 4
gpt4 key购买 nike

我正在尝试测试我的 Spring Rest 客户端,但遇到了麻烦。这是我的客户端类:

@Component
public class MyClient{

private RestTemplate restTemplate;


@Autowired
public MyClient(RestTemplateBuilder restTemplateBuilder,ResponseErrorHandler myResponseErrorHandler) {
this.restTemplate = restTemplateBuilder
.errorHandler(myResponseErrorHandler)
.build();
}
//other codes here
}

这里 myResponseErrorHandler是覆盖 handleError 的类和 hasError ResponseErrorHandler 的方法类(class)。

现在我的测试课是

    @RunWith(SpringRunner.class)
public class MyClientTest {

@InjectMocks
MyClient myClient;
@Mock
RestTemplate restTemplate;
@Mock
RestTemplateBuilder restTemplateBuilder;

//test cases here
}

但是我收到如下错误,我不知道如何解决这个问题。
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : null

最佳答案

这个问题是因为当你正常运行你的应用程序时,Spring Boot 会配置 RestTemplateBuilder自动为您提供(因为 @SpringBootApplication 注释),但在您的测试中您没有相应的 @SpringBootTest注释和 restTemplateBuilder在 MyClient 的构造函数中当然是 null (在尝试调用 build() 方法时会产生错误)。

如果按原样添加它,它将使用应用程序默认配置上下文,以及 RestTemplateBuilderMyResponseErrorHandler将是工作 bean(请注意,在这种情况下, MyClientMyResponseErrorHandler 都应该被配置为 bean - 例如用 @Component 标记它们)。

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyClientTest {

@Autowired
private MyClient myClient;

@Mock
private MyResponseErrorHandler myResponseErrorHandler;

@Test
public void sampleTest() throws IOException {
//The example of configuring myResponseErrorHandler behavior
Mockito.when(myResponseErrorHandler.hasError(Mockito.any())).thenReturn(true);

//Call myClient method

//Asserts...
}
}

另外,不要对 RestTemplate 做任何事情,因为它将在 MyClient 构造函数中以编程方式创建。

另一种方法 就是创建一个单独的测试配置,在这里可以得到默认的 RestTemplateBuilder bean(由 Spring 提供)和模拟 MyResponseErrorHandler (用于稍后配置其行为)。它可以让您完全控制如何在不使用应用程序上下文的情况下为测试配置所有 bean。

如果你想深入研究 - 这里是实现这一目标的步骤:
  • 使用 MyResponseErrorHandler 创建测试配置类 bean :

  • @TestConfiguration
    public class MyClientTestConfiguration {

    @Autowired
    private RestTemplateBuilder restTemplateBuilder;

    @Bean
    public ResponseErrorHandler myResponseErrorHandler() {
    return Mockito.mock(MyResponseErrorHandler.class);
    }


    @Bean
    public MyClient myClient() {
    return new MyClient(restTemplateBuilder, myResponseErrorHandler());
    }
    }
  • 你的测试类应该是这样的:

  • @RunWith(SpringRunner.class)
    @SpringBootTest(classes = MyClientTestConfiguration.class)
    public class MyClientTest {

    @Autowired //wired from MyClientTestConfiguration class
    private MyClient myClient;

    @Autowired //wired from MyClientTestConfiguration class
    private MyResponseErrorHandler myResponseErrorHandler;

    @Test
    public void sampleTest() throws IOException {
    //The example of configuring myResponseErrorHandler behavior
    Mockito.when(myResponseErrorHandler.hasError(Mockito.any())).thenReturn(true);

    //Calling myClient method...

    //Asserts...
    }
    }

    关于junit - 在 Spring 中模拟 RestTemplate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54875794/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com