MockBean stubbing ineffective
I have a configuration class with a few MockBeans replacing actual beans in context for tests.
@Configuration
public class MyTestConfig {
@MockBean
private MyService myService;
}
I use those mocks in my tests:
@Import({ MyTestConfig .class })
public class MyTest {
@Autowired
private MyService myService;
@Test
public void aTest() {
...
}
}
First the idea was to add the stubbing in this MyTestConfig
configuration class, so that the mock is pre-made for all tests, so I did it in a @PostConstruct
method, and it worked just fine - the mock in test did return the expected value:
@PostConstruct
public void init() {
when(myService.foo("say hello")).thenReturn("Hello world");
}
It turned out though, that constructing a pre-made mock suitable for all test can be tricky, so we decided to move the stubbing to tests.
@Test
public void aTest() {
when(myService.foo("say hello")).thenReturn("Hello world");
}
And this doesn't work - the stubbed method returns null
. We want to leave MockBeans in the configuration class, but stub them in tests, so any advice on why the stubbing is ineffective?
Spring Boot 2.0.5, Mockito 2.22.0
spring spring-boot testing mocking mockito
add a comment |
I have a configuration class with a few MockBeans replacing actual beans in context for tests.
@Configuration
public class MyTestConfig {
@MockBean
private MyService myService;
}
I use those mocks in my tests:
@Import({ MyTestConfig .class })
public class MyTest {
@Autowired
private MyService myService;
@Test
public void aTest() {
...
}
}
First the idea was to add the stubbing in this MyTestConfig
configuration class, so that the mock is pre-made for all tests, so I did it in a @PostConstruct
method, and it worked just fine - the mock in test did return the expected value:
@PostConstruct
public void init() {
when(myService.foo("say hello")).thenReturn("Hello world");
}
It turned out though, that constructing a pre-made mock suitable for all test can be tricky, so we decided to move the stubbing to tests.
@Test
public void aTest() {
when(myService.foo("say hello")).thenReturn("Hello world");
}
And this doesn't work - the stubbed method returns null
. We want to leave MockBeans in the configuration class, but stub them in tests, so any advice on why the stubbing is ineffective?
Spring Boot 2.0.5, Mockito 2.22.0
spring spring-boot testing mocking mockito
1
I'm actually surprised that@MockBean
works in a configuration class as it shouldn't. Also the use of@Import
on your test class is something you shouldn't be doing. If you want to globally mock beans you will need to create the mock yourself usingMockito.mock
inside an@Bean
method to have reliable mocking. Else use an@Autowired
field in your testcase which you want to use the mocked instance. Also instead of@Import
you should specify this in your@SpringBootTest
or@ContextConfiguration
as class to use for configuration.
– M. Deinum
Nov 23 '18 at 8:08
@M.Deinum The documentation of@MockBean
states: Can be used as a class level annotation or on fields in either @Configuration classes, or test classes that are @RunWith the SpringRunner, so it's definitely supposed to work in configuration class. Defining a plain mock in @Bean method would be fine if the stubbing in test worked, but it doesn't, so that's not an option either.
– snw
Nov 23 '18 at 8:38
1
If stubbing doesn't work you must be doing weird things. We use this literally in hundreds of testcases and works like a charm. Are you defining the correct stubbing for the actions you want to perform?
– M. Deinum
Nov 23 '18 at 8:40
@M.Deinum Turns our my problem description is insufficient, because I skipped quite an important detail, but you did help me figure it out anyway. What I didn't say (aiming to keep it simple) is that my test is an@WebMvcTest
with@WithUserDetails
, and my service is a dependency of a customUserDetailsManager
. Spring Security makes the call toUserDetailsManager
before the actual test content. That's why the stubbing in test had no effect, and that's why it worked fine when the mock was stubbed in config's@PostConstruct
. Thanks for your help.
– snw
Nov 23 '18 at 9:05
add a comment |
I have a configuration class with a few MockBeans replacing actual beans in context for tests.
@Configuration
public class MyTestConfig {
@MockBean
private MyService myService;
}
I use those mocks in my tests:
@Import({ MyTestConfig .class })
public class MyTest {
@Autowired
private MyService myService;
@Test
public void aTest() {
...
}
}
First the idea was to add the stubbing in this MyTestConfig
configuration class, so that the mock is pre-made for all tests, so I did it in a @PostConstruct
method, and it worked just fine - the mock in test did return the expected value:
@PostConstruct
public void init() {
when(myService.foo("say hello")).thenReturn("Hello world");
}
It turned out though, that constructing a pre-made mock suitable for all test can be tricky, so we decided to move the stubbing to tests.
@Test
public void aTest() {
when(myService.foo("say hello")).thenReturn("Hello world");
}
And this doesn't work - the stubbed method returns null
. We want to leave MockBeans in the configuration class, but stub them in tests, so any advice on why the stubbing is ineffective?
Spring Boot 2.0.5, Mockito 2.22.0
spring spring-boot testing mocking mockito
I have a configuration class with a few MockBeans replacing actual beans in context for tests.
@Configuration
public class MyTestConfig {
@MockBean
private MyService myService;
}
I use those mocks in my tests:
@Import({ MyTestConfig .class })
public class MyTest {
@Autowired
private MyService myService;
@Test
public void aTest() {
...
}
}
First the idea was to add the stubbing in this MyTestConfig
configuration class, so that the mock is pre-made for all tests, so I did it in a @PostConstruct
method, and it worked just fine - the mock in test did return the expected value:
@PostConstruct
public void init() {
when(myService.foo("say hello")).thenReturn("Hello world");
}
It turned out though, that constructing a pre-made mock suitable for all test can be tricky, so we decided to move the stubbing to tests.
@Test
public void aTest() {
when(myService.foo("say hello")).thenReturn("Hello world");
}
And this doesn't work - the stubbed method returns null
. We want to leave MockBeans in the configuration class, but stub them in tests, so any advice on why the stubbing is ineffective?
Spring Boot 2.0.5, Mockito 2.22.0
spring spring-boot testing mocking mockito
spring spring-boot testing mocking mockito
asked Nov 23 '18 at 7:36
snwsnw
1,190713
1,190713
1
I'm actually surprised that@MockBean
works in a configuration class as it shouldn't. Also the use of@Import
on your test class is something you shouldn't be doing. If you want to globally mock beans you will need to create the mock yourself usingMockito.mock
inside an@Bean
method to have reliable mocking. Else use an@Autowired
field in your testcase which you want to use the mocked instance. Also instead of@Import
you should specify this in your@SpringBootTest
or@ContextConfiguration
as class to use for configuration.
– M. Deinum
Nov 23 '18 at 8:08
@M.Deinum The documentation of@MockBean
states: Can be used as a class level annotation or on fields in either @Configuration classes, or test classes that are @RunWith the SpringRunner, so it's definitely supposed to work in configuration class. Defining a plain mock in @Bean method would be fine if the stubbing in test worked, but it doesn't, so that's not an option either.
– snw
Nov 23 '18 at 8:38
1
If stubbing doesn't work you must be doing weird things. We use this literally in hundreds of testcases and works like a charm. Are you defining the correct stubbing for the actions you want to perform?
– M. Deinum
Nov 23 '18 at 8:40
@M.Deinum Turns our my problem description is insufficient, because I skipped quite an important detail, but you did help me figure it out anyway. What I didn't say (aiming to keep it simple) is that my test is an@WebMvcTest
with@WithUserDetails
, and my service is a dependency of a customUserDetailsManager
. Spring Security makes the call toUserDetailsManager
before the actual test content. That's why the stubbing in test had no effect, and that's why it worked fine when the mock was stubbed in config's@PostConstruct
. Thanks for your help.
– snw
Nov 23 '18 at 9:05
add a comment |
1
I'm actually surprised that@MockBean
works in a configuration class as it shouldn't. Also the use of@Import
on your test class is something you shouldn't be doing. If you want to globally mock beans you will need to create the mock yourself usingMockito.mock
inside an@Bean
method to have reliable mocking. Else use an@Autowired
field in your testcase which you want to use the mocked instance. Also instead of@Import
you should specify this in your@SpringBootTest
or@ContextConfiguration
as class to use for configuration.
– M. Deinum
Nov 23 '18 at 8:08
@M.Deinum The documentation of@MockBean
states: Can be used as a class level annotation or on fields in either @Configuration classes, or test classes that are @RunWith the SpringRunner, so it's definitely supposed to work in configuration class. Defining a plain mock in @Bean method would be fine if the stubbing in test worked, but it doesn't, so that's not an option either.
– snw
Nov 23 '18 at 8:38
1
If stubbing doesn't work you must be doing weird things. We use this literally in hundreds of testcases and works like a charm. Are you defining the correct stubbing for the actions you want to perform?
– M. Deinum
Nov 23 '18 at 8:40
@M.Deinum Turns our my problem description is insufficient, because I skipped quite an important detail, but you did help me figure it out anyway. What I didn't say (aiming to keep it simple) is that my test is an@WebMvcTest
with@WithUserDetails
, and my service is a dependency of a customUserDetailsManager
. Spring Security makes the call toUserDetailsManager
before the actual test content. That's why the stubbing in test had no effect, and that's why it worked fine when the mock was stubbed in config's@PostConstruct
. Thanks for your help.
– snw
Nov 23 '18 at 9:05
1
1
I'm actually surprised that
@MockBean
works in a configuration class as it shouldn't. Also the use of @Import
on your test class is something you shouldn't be doing. If you want to globally mock beans you will need to create the mock yourself using Mockito.mock
inside an @Bean
method to have reliable mocking. Else use an @Autowired
field in your testcase which you want to use the mocked instance. Also instead of @Import
you should specify this in your @SpringBootTest
or @ContextConfiguration
as class to use for configuration.– M. Deinum
Nov 23 '18 at 8:08
I'm actually surprised that
@MockBean
works in a configuration class as it shouldn't. Also the use of @Import
on your test class is something you shouldn't be doing. If you want to globally mock beans you will need to create the mock yourself using Mockito.mock
inside an @Bean
method to have reliable mocking. Else use an @Autowired
field in your testcase which you want to use the mocked instance. Also instead of @Import
you should specify this in your @SpringBootTest
or @ContextConfiguration
as class to use for configuration.– M. Deinum
Nov 23 '18 at 8:08
@M.Deinum The documentation of
@MockBean
states: Can be used as a class level annotation or on fields in either @Configuration classes, or test classes that are @RunWith the SpringRunner, so it's definitely supposed to work in configuration class. Defining a plain mock in @Bean method would be fine if the stubbing in test worked, but it doesn't, so that's not an option either.– snw
Nov 23 '18 at 8:38
@M.Deinum The documentation of
@MockBean
states: Can be used as a class level annotation or on fields in either @Configuration classes, or test classes that are @RunWith the SpringRunner, so it's definitely supposed to work in configuration class. Defining a plain mock in @Bean method would be fine if the stubbing in test worked, but it doesn't, so that's not an option either.– snw
Nov 23 '18 at 8:38
1
1
If stubbing doesn't work you must be doing weird things. We use this literally in hundreds of testcases and works like a charm. Are you defining the correct stubbing for the actions you want to perform?
– M. Deinum
Nov 23 '18 at 8:40
If stubbing doesn't work you must be doing weird things. We use this literally in hundreds of testcases and works like a charm. Are you defining the correct stubbing for the actions you want to perform?
– M. Deinum
Nov 23 '18 at 8:40
@M.Deinum Turns our my problem description is insufficient, because I skipped quite an important detail, but you did help me figure it out anyway. What I didn't say (aiming to keep it simple) is that my test is an
@WebMvcTest
with @WithUserDetails
, and my service is a dependency of a custom UserDetailsManager
. Spring Security makes the call to UserDetailsManager
before the actual test content. That's why the stubbing in test had no effect, and that's why it worked fine when the mock was stubbed in config's @PostConstruct
. Thanks for your help.– snw
Nov 23 '18 at 9:05
@M.Deinum Turns our my problem description is insufficient, because I skipped quite an important detail, but you did help me figure it out anyway. What I didn't say (aiming to keep it simple) is that my test is an
@WebMvcTest
with @WithUserDetails
, and my service is a dependency of a custom UserDetailsManager
. Spring Security makes the call to UserDetailsManager
before the actual test content. That's why the stubbing in test had no effect, and that's why it worked fine when the mock was stubbed in config's @PostConstruct
. Thanks for your help.– snw
Nov 23 '18 at 9:05
add a comment |
1 Answer
1
active
oldest
votes
Yes, stubbing should be performed inside their respective test cases (unless you have a test class that shares the stubbing scenarios but it all comes down to preference).
However, for creating @MockBeans
, you would need to use a @SpringBootTest
in order to get the actual beans replaced with mocks. This could be done as simply as this example:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTest {
@Autowired
private MyTestClass testClass;
@MockBean
private MyService service;
@Test
public void myTest() {
// testing....
}
}
The bean is actually replaced with a mock.MockUtil.isMock(myService)
returnstrue
in test. The only issue is that the stubbing performed in test has no effect.
– snw
Nov 23 '18 at 8:41
1
Are you using@SpringBootTest
and aSpringRunner
to run your tests?
– Urosh T.
Nov 23 '18 at 8:48
I figured it out, see my comments under the question. Thanks for help!
– snw
Nov 23 '18 at 9:06
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53442430%2fmockbean-stubbing-ineffective%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Yes, stubbing should be performed inside their respective test cases (unless you have a test class that shares the stubbing scenarios but it all comes down to preference).
However, for creating @MockBeans
, you would need to use a @SpringBootTest
in order to get the actual beans replaced with mocks. This could be done as simply as this example:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTest {
@Autowired
private MyTestClass testClass;
@MockBean
private MyService service;
@Test
public void myTest() {
// testing....
}
}
The bean is actually replaced with a mock.MockUtil.isMock(myService)
returnstrue
in test. The only issue is that the stubbing performed in test has no effect.
– snw
Nov 23 '18 at 8:41
1
Are you using@SpringBootTest
and aSpringRunner
to run your tests?
– Urosh T.
Nov 23 '18 at 8:48
I figured it out, see my comments under the question. Thanks for help!
– snw
Nov 23 '18 at 9:06
add a comment |
Yes, stubbing should be performed inside their respective test cases (unless you have a test class that shares the stubbing scenarios but it all comes down to preference).
However, for creating @MockBeans
, you would need to use a @SpringBootTest
in order to get the actual beans replaced with mocks. This could be done as simply as this example:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTest {
@Autowired
private MyTestClass testClass;
@MockBean
private MyService service;
@Test
public void myTest() {
// testing....
}
}
The bean is actually replaced with a mock.MockUtil.isMock(myService)
returnstrue
in test. The only issue is that the stubbing performed in test has no effect.
– snw
Nov 23 '18 at 8:41
1
Are you using@SpringBootTest
and aSpringRunner
to run your tests?
– Urosh T.
Nov 23 '18 at 8:48
I figured it out, see my comments under the question. Thanks for help!
– snw
Nov 23 '18 at 9:06
add a comment |
Yes, stubbing should be performed inside their respective test cases (unless you have a test class that shares the stubbing scenarios but it all comes down to preference).
However, for creating @MockBeans
, you would need to use a @SpringBootTest
in order to get the actual beans replaced with mocks. This could be done as simply as this example:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTest {
@Autowired
private MyTestClass testClass;
@MockBean
private MyService service;
@Test
public void myTest() {
// testing....
}
}
Yes, stubbing should be performed inside their respective test cases (unless you have a test class that shares the stubbing scenarios but it all comes down to preference).
However, for creating @MockBeans
, you would need to use a @SpringBootTest
in order to get the actual beans replaced with mocks. This could be done as simply as this example:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTest {
@Autowired
private MyTestClass testClass;
@MockBean
private MyService service;
@Test
public void myTest() {
// testing....
}
}
answered Nov 23 '18 at 8:16
Urosh T.Urosh T.
66711116
66711116
The bean is actually replaced with a mock.MockUtil.isMock(myService)
returnstrue
in test. The only issue is that the stubbing performed in test has no effect.
– snw
Nov 23 '18 at 8:41
1
Are you using@SpringBootTest
and aSpringRunner
to run your tests?
– Urosh T.
Nov 23 '18 at 8:48
I figured it out, see my comments under the question. Thanks for help!
– snw
Nov 23 '18 at 9:06
add a comment |
The bean is actually replaced with a mock.MockUtil.isMock(myService)
returnstrue
in test. The only issue is that the stubbing performed in test has no effect.
– snw
Nov 23 '18 at 8:41
1
Are you using@SpringBootTest
and aSpringRunner
to run your tests?
– Urosh T.
Nov 23 '18 at 8:48
I figured it out, see my comments under the question. Thanks for help!
– snw
Nov 23 '18 at 9:06
The bean is actually replaced with a mock.
MockUtil.isMock(myService)
returns true
in test. The only issue is that the stubbing performed in test has no effect.– snw
Nov 23 '18 at 8:41
The bean is actually replaced with a mock.
MockUtil.isMock(myService)
returns true
in test. The only issue is that the stubbing performed in test has no effect.– snw
Nov 23 '18 at 8:41
1
1
Are you using
@SpringBootTest
and a SpringRunner
to run your tests?– Urosh T.
Nov 23 '18 at 8:48
Are you using
@SpringBootTest
and a SpringRunner
to run your tests?– Urosh T.
Nov 23 '18 at 8:48
I figured it out, see my comments under the question. Thanks for help!
– snw
Nov 23 '18 at 9:06
I figured it out, see my comments under the question. Thanks for help!
– snw
Nov 23 '18 at 9:06
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53442430%2fmockbean-stubbing-ineffective%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
I'm actually surprised that
@MockBean
works in a configuration class as it shouldn't. Also the use of@Import
on your test class is something you shouldn't be doing. If you want to globally mock beans you will need to create the mock yourself usingMockito.mock
inside an@Bean
method to have reliable mocking. Else use an@Autowired
field in your testcase which you want to use the mocked instance. Also instead of@Import
you should specify this in your@SpringBootTest
or@ContextConfiguration
as class to use for configuration.– M. Deinum
Nov 23 '18 at 8:08
@M.Deinum The documentation of
@MockBean
states: Can be used as a class level annotation or on fields in either @Configuration classes, or test classes that are @RunWith the SpringRunner, so it's definitely supposed to work in configuration class. Defining a plain mock in @Bean method would be fine if the stubbing in test worked, but it doesn't, so that's not an option either.– snw
Nov 23 '18 at 8:38
1
If stubbing doesn't work you must be doing weird things. We use this literally in hundreds of testcases and works like a charm. Are you defining the correct stubbing for the actions you want to perform?
– M. Deinum
Nov 23 '18 at 8:40
@M.Deinum Turns our my problem description is insufficient, because I skipped quite an important detail, but you did help me figure it out anyway. What I didn't say (aiming to keep it simple) is that my test is an
@WebMvcTest
with@WithUserDetails
, and my service is a dependency of a customUserDetailsManager
. Spring Security makes the call toUserDetailsManager
before the actual test content. That's why the stubbing in test had no effect, and that's why it worked fine when the mock was stubbed in config's@PostConstruct
. Thanks for your help.– snw
Nov 23 '18 at 9:05