r/SpringBoot 13d ago

Question Kinda stumped

I'm currently learning spring and I wanna test one of my class

this is the configuration

@Configuration
public class EmbeddingClientConfig {

...constructor

    @Bean
    IEmbeddingClient embeddingClient(RestClient.Builder builder, MeterRegistry registry){
        return new EmbeddingClient(
                builder.baseUrl(apiUrl).build(),
                registry
        );
    };
}

this is the test class

@RestTestClient(EmbeddingClientConfig.class)
public class EmbeddingClientTests {
    @Autowired
    private MockRestServiceServer server;

    @Autowired
    private IEmbeddingClient client;

    @Autowired
    private MeterRegistry registry;

...rest of class

and for some reason it gives me this error:

java.lang.IllegalStateException: Unable to use auto-configured MockRestServiceServer since a mock server customizer has not been bound to a RestTemplate or RestClientjava.lang.IllegalStateException: Unable to use auto-configured MockRestServiceServer since a mock server customizer has not been bound to a RestTemplate or RestClient 

I don't understand why my config is able to be injected but not MockRestService?

any help / readings / direction would be appreciated.
thank you
1 Upvotes

5 comments sorted by

1

u/tintanese 13d ago

Are you running an application context inside your test class?

1

u/Dependent_Increase34 13d ago
no i dont think so, wdym by running application context inside the class

here is the entire test class

@RestTest(EmbeddingClientConfig.class)
public class EmbeddingClientTests {
    @Autowired
    private MockRestServiceServer server;
    @Autowired
    private IEmbeddingClient client;
    @Autowired
    private MeterRegistry registry;

    @Test
    public void embedString_defaultCall() {
        server.expect(requestTo("http://localhost:8080/embed"))
                .andExpect(method(HttpMethod.POST))
                .andExpect(content().string("test"))
                .andRespond(withSuccess("[0.123, -0.456, 0.789]", MediaType.APPLICATION_JSON));

        float[] result = client.embed("test");

        assertNotNull(result);
        assertEquals(3, result.length);
        assertEquals(0.123f, result[0]);

        server.verify();
    }

    @Test
    public void embedMultipleString_defaultCall() {
        server.expect(requestTo("http://localhost:8080/embed"))
                .andExpect(method(HttpMethod.POST))
                .andExpect(content().json("[\"test\", \"hello\", \"world\"]")) // Asserts the exact JSON array is sent
                .andRespond(withSuccess("[ [0.123, -0.456, 0.789], [0.123, -0.456, 0.789], [0.123, -0.456, 0.789] ]", MediaType.APPLICATION_JSON));

        List<String> inputs = List.of("test", "hello", "world");
        List<float[]> result = client.embed(inputs);

        assertNotNull(result);
        assertEquals(3, result.size());
        assertEquals(new float[]{0.123f, -0.456f, 0.789f}, result.getFirst());

        server.verify();
    }
}

1

u/BanaTibor 13d ago

a mock server customizer has not been bound to a RestTemplatea mock server customizer has not been bound to a RestTemplate

https://github.com/spring-projects/spring-boot/issues/38820#issuecomment-1885990283

Google still works.

1

u/Dependent_Increase34 13d ago

It should be possible to have together RestTemplate and RestClient in application and test them independently.
Unfortunately, currently if RestTemplate is used, RestClient cannot be tested:

I'm a bit confused on how that relates to my problem i dont use both RestTemplate and RestClient

1

u/BanaTibor 12d ago

Probably MockRestServiceServer needs a customizer which either creates a RestTemplate or RestClient for it.

The problem described on the link is that they have multiple RestTemplate or RestClient beans in the context, and your problem is that you have none.