1

I'm using Mockio, Wiremock and WebClient and I want to test my service layer. My goal is to use an instance of the webclient and do a real request to wiremock.

Therefore I have to use a standard configuration and not my oauth config from the production mode.

In the service class, I execute reuqets to another api. So the class under test ist annotated with @Service.

Here is the class:

@Service
public class UserServiceImpl implements UserService{

    private final Logger log = Logger.getLogger(this.getClass().getName());
    private final WebClient webClient;
    private final ApplicationConstants applicationConstants;

    public UserServiceImpl (WebClient webClient, ApplicationConstants applicationConstants) {
        this.applicationConstants = applicationConstants;
        this.webClient = webClient;
    }

    @Override
    public User getUserById(@NotNull(message = "userId must not be null.") @NotBlank(message = "userId must not be blank.") String userId) {
        return  webClient.get()...
}

I configured my WebClient to use Oauth via two Bean Methods in a class annotated with @Configuration.

@Configuration
public class WebClientConfig {

    @Bean
    public WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {
       ...
    }

    /*
    Manages the auth process and token refresh process
     */
    @Bean
    public OAuth2AuthorizedClientManager authorizedClientManager(
            ClientRegistrationRepository clientRegistrationRepository,
            OAuth2AuthorizedClientRepository authorizedClientRepository) {

        ...
    }
}

Because I want to use the webClient without oauth to call wiremock, I want to replace the Beans to return a simple Webclient.builder().build();

So I did:

@ExtendWith({SpringExtension.class, WireMockExtension.class, MockitoExtension.class})
public class TestClass {

    @Mock
    WebClientConfig webClientConfig;

    @MockBean
    WebClient webClient;

    @InjectMocks 
    UserServiceImpl userService;

In general as I understand Mockito, i would use my class under test ( the userServiceImpl) with @InjectMocks, so a real instance is used and the dependencies are injected. Therefor I have to provide a Mock for the Webclient. As I don't want to Mock the webclient and just want to configure it different, I do not have to use @Mock. Instead it should be somethig like @MockBean as this annotation creates a bean and replaces existing ones in the context. So I have to mock the Webclientconfig class with @Mock and define something like

when(webclientConfig).webclient(any(OAuth2AuthorizedClientManager.class)).thenReturn(Webclient.builder.build);

But this does not work as I always get a nullpointer exception on the call. So the basic questions are:

  1. Is my understanding of Mockito right?
  2. How do I have to Manage the Webclient config?
FishingIsLife
  • 1,972
  • 3
  • 28
  • 51

1 Answers1

0

Looks like a case of configuring MockBeans before the rest of the application starts up, which is answered here: Configure @MockBean component before application start

As of this writing, the answer above mentions using @Primary or @MockBean(answer = Answers.CALLS_REAL_METHODS) as workarounds.

Alexander Taylor
  • 16,574
  • 14
  • 62
  • 83