WebClient是否可以在PostConstruct方法中初始化时进行模拟?

huangapple go评论78阅读模式
英文:

Can webClient be mocked if it's initialised in PostConstruct method?

问题

我有一个包含私有WebClient的类,该WebClient是通过PostConstruct初始化的。
我想要模拟它,以避免调用真正的端点,但我不知道如何为这个对象创建模拟。因为它不是通过字段或构造函数初始化的。
有人能指导如何在不使用反射的情况下进行模拟吗?
谢谢。

英文:

I have a class with private WebClient which is initialised via PostConstruct.
I would like to mock it to not call real endpoints, but I have't got any idea how I can create mock for this object. As it't not initialised via a field or a constructor.
Can anyone advise how to it can be mocked without using reflection?
Thank you.

@Service
@RequiredArgsConstructor
public class TestServiceImpl implements TestService {

  private final ServiceB serviceB;

  private WebClient webClient;

  @PostConstruct
  public void init() {

    this.webClient = WebClient.builder()
        .baseUrl(baseUrl)
        .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
        .clientConnector(new ReactorClientHttpConnector(new HttpClient()))
        .build();
  }

  @Override
  public String request(String body) {
    return this.requestString(body)
        .bodyToMono(String.class)
        .block();
  }

  public WebClient.ResponseSpec requestString(String body) {

    return webClient
        .post()
        .uri(uriBuilder -> uriBuilder
            .path("/test/{id}/")
            .build(1))
        .bodyValue(body)
        .retrieve();
  }
}

答案1

得分: 1

你需要摒弃PostContruct的初始化,只需创建一个WebClient bean,并让Spring注入到你的类中:

@Configuration
public class SomeConfig {

	@Bean
	public WebClient webClient() {
		return WebClient.builder()
			.baseUrl(baseUrl)
			.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
			.clientConnector(new ReactorClientHttpConnector(new HttpClient()))
			.build();
	}
}

因此,在重构后,你的类将如下所示,现在你可以轻松地进行模拟:

@Service
@RequiredArgsConstructor
public class TestServiceImpl implements TestService {

	private final ServiceB serviceB;

	private final WebClient webClient;

	@Override
	public String request(String body) {
		return this.requestString(body)
			.bodyToMono(String.class)
			.block();
	}

	public WebClient.ResponseSpec requestString(String body) {
		return webClient
			.post()
			.uri(uriBuilder -> uriBuilder
				.path("/test/{id}/")
				.build(1))
			.bodyValue(body)
			.retrieve();
	}
}
英文:

You need to get rid of the PostContruct initialization and
just create a WebClient bean and let spring to inject it in your class:

@Configuration
public class SomeConfig {


	@Bean
   public WebClient webClient() {
		WebClient.builder()
        .baseUrl(baseUrl)
        .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
        .clientConnector(new ReactorClientHttpConnector(new HttpClient()))
        .build();
   }
}

So, your class would look like this after refactoring, now you can mock them easily:

@Service
@RequiredArgsConstructor
public class TestServiceImpl implements TestService {

  private final ServiceB serviceB;

  private final WebClient webClient;

  @Override
  public String request(String body) {
    return this.requestString(body)
        .bodyToMono(String.class)
        .block();
  }

  public WebClient.ResponseSpec requestString(String body) {

    return webClient
        .post()
        .uri(uriBuilder -> uriBuilder
            .path("/test/{id}/")
            .build(1))
        .bodyValue(body)
        .retrieve();
  }
}

huangapple
  • 本文由 发表于 2023年8月4日 03:20:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76831056.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定