Is it possible to somehow have in the same test class @MockBean
and @Autowired
of the same service?
In other words, I would like to have @MockBean
service only for one test, while for others tests of the same class I need it as @Autowired
.
Autowiring using property type. Allows a property to be autowired if exactly one bean of property type exists in the container. If more than one exists, it's a fatal exception is thrown, which indicates that you may not used byType autowiring for that bean.
A class that uses the repository class: public class MyClass extends AbstractClass { @Autowired private MyRepository myRepository; //... } I know that if I annotate my MyClass with @Component and use it with an @Autowired , then the @Autowired MyRepository is resolved just fine.
We can use the @MockBean to add mock objects to the Spring application context. The mock will replace any existing bean of the same type in the application context. If no bean of the same type is defined, a new one will be added.
@Bean is just for the metadata definition to create the bean(equivalent to tag). @Autowired is to inject the dependancy into a bean(equivalent to ref XML tag/attribute).
This relies on the difference between @MockBean
and @Autowired
.
@Autowired
only does a lookup in the SpringContext
for a bean of that type. This means that you will need to create that bean if you need to 'autowire' it
@MockBean
does exactly what you expect from the name, it creates a 'mock' of the service, and injects it as a bean.
so this
class MyTest {
@MockBean
MyService myService;
}
is equivalent to this
@Import(MyTest.Config.class)
class MyTest {
@Autowired
MyService myService;
@TestConfiguration
static class Config {
@Bean
MyService myService() {
return Mockito.mock(MyService.class);
}
}
}
So, if you need to have a different bean of the MyService
type in other tests, you need to create the bean in a @TestConfiguration
annotated class
@Import(MyTest.Config.class)
class MyTest {
@Autowired
MyService myService;
@TestConfiguration
static class Config {
@Bean
MyService myService() {
return new MyServiceImpl();
}
}
}
Or, in a class annotated with @Configuration
@Import(MyConfig.class)
class MyTest {
@Autowired
MyService myService;
}
@Configuration
public class MyConfig {
@Bean
MyService myService() {
return new MyServiceImpl();
}
}
The best solution is to change @MockBean
to @SpyBean. And in the method you will be able to do like this:
kotlin
@SpyBean
lateinit var serviceMock: Service
@Test
fun smallTest()
`when`(serviceMock.doSomething())
.thenReturn(false)
// your test logic
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With