Open
Description
Trying to define mock for request-scoped supplier does not work unless I explicitly name the mock.
The problem with hardcoding bean name is that name can be dependent on configuration (for example via use conditions).
If there is no RequestScope
or I use custom interface there is no such problem.
Spring Boot 2.7.8 + JDK17
Simplified program:
package com.example.testspringoverridebeantest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.springframework.web.context.annotation.RequestScope;
import java.util.function.Supplier;
@SpringBootApplication
public class TestSpringOverrideBeanTestApplication {
@Bean
@RequestScope
Supplier<String> word() {
return () -> "app";
}
@Bean
@RequestScope
@Profile("test") // just an example condition
@Primary
Supplier<String> testWord() {
return () -> "testapp";
}
public static void main(String[] args) {
SpringApplication.run(TestSpringOverrideBeanTestApplication.class, args);
}
}
@Service
record Greeter(Supplier<String> word) {
String hello() {
return "hello, " + word.get();
}
}
package com.example.testspringoverridebeantest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import java.util.function.Supplier;
@SpringBootTest
class TestSpringOverrideBeanTestApplicationTests {
@Autowired
Greeter greeter;
@MockBean// (name = "testWord") // unbreaks but the name can vary!
Supplier<String> word;
@Test
void canOverrideBeanForTest() {
Mockito.when(word.get()).thenReturn("test");
Assertions.assertEquals("hello, test", greeter.hello());
}
}