Why @MockBean Environment(Interface) doesn't work in @WebMvcTest annotated controller class Junit 5 However same thing is working fine in Service layer here service layer doesn't have @WebMvcTest annotation.
Is this a bug or i am missing something?
Jupiter Version : 5.8.1 Spring boot 2.3.4.RELEASE Java 8
Comment From: arvindersinghchhabra
I posted to Junit but they redirected to me here.
Comment From: philwebb
I’m sorry, but I don’t understand the question. Could you please provide a sample application either as a GitHub project or an attached zip file that shows the problem?
Comment From: arvindersinghchhabra
Please see the sample code below.
//Spring boot project
// Controller Class
@ContextConfiguration(classes = {DemoController.class})
@WebMvcTest(DemoController.class)
@AutoConfiguration(addFilters= false)
class DemoControllerTest{
@Autowired
private MockMvc mockMvc;
@MockBean // Not working here at controller layer see below service layer code its working fine at service layer. However
private Environment environment;
@Test
void test(){
// mockMvc code
}
}
// Service Layer
@ExtendWith(springExtension.class)
@ContextConfiguration(classes = {DemoService.class})
public class DemoService
{
@Autowired
private DemoService demoService;
@MockBean // working perfectly here but something is wrong with controller, same thing is not working in above controller.
private Environment environment;
@Test
public void test(){
when(environment.getActiveProfiles()).thenReturn(new String[]{'local'}); // working perfectly here
}
}
Comment From: philwebb
Environment
isn't a a bean and cannot be mocked with @MockBean
. You should consider using @ActiveProfiles("local")
or @TestPropertySource(properties="spring.profiles.active=local")
if you want to activate specific profiles in your tests.
Comment From: arvindersinghchhabra
Then how same code in working in Service layer.
I posted service layer code as well
Comment From: snicoll
For a start, this isn't "the service layer". This a JUnit test using the core TCF infrastructure. Your slice test is using the Spring Boot infrastructure and auto-configuration that requires extra processing on the environment. That is way your simple test that doesn't touch the environment at all works, and not the slice test.
That said, as Phil already explained above, you cannot mock the Environment
as whatever configuration you'd apply on your test will be applied after the context has refreshed.
Comment From: arvindersinghchhabra
Thanks @snicoll but still just a confusion, as per Phil we can't use @MockBean
with Environment
interface then this rule should be applicable for every place. How developers will get to know where and when to use @MockBean
with interface Environment
.
Comment From: philwebb
I can see why it working in one test and not the other would be confusing. We'd need a sample application either as an attached zip
file or a share GitHub project from you to get to the bottom of why that's happening.