Reputation: 716
I am using simple converter for converting string to enum. Here is the custom converter:
@Component
public class SessionStateConverter implements Converter<String, UserSessionState> {
@Override
public UserSessionState convert(String source) {
try {
return UserSessionState.valueOf(source.toUpperCase());
} catch (Exception e) {
LOG.debug(String.format("Invalid UserSessionState value was provided: %s", source), e);
return null;
}
}
}
Currently I am using UserSessionState as PathVariable
in my rest controller. The implementation works as expected. However when I try to unit test the rest controller it seems that conversion does not work and it does not hit the controller method.
@RunWith(MockitoJUnitRunner.class)
public class MyTest {
private MockMvc mockMvc;
@Mock
private FormattingConversionService conversionService;
@InjectMocks
private MynController controller;
@Before
public void setup() {
conversionService.addConverter(new SessionStateConverter());
mockMvc = MockMvcBuilders.standaloneSetup(controller).setConversionService(conversionService).build();
}
@Test
public void testSetLoginUserState() throws Exception {
mockMvc.perform(post("/api/user/login"));
}
}
In debug mode I get following error:
nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'rest.api.UserSessionState': no matching editors or conversion strategy found
In my opinion the mock for conversion service does not work. Any ideas?
Upvotes: 5
Views: 7678
Reputation: 3677
For anyone using SpringBootTest with AutoConfigureMockMvc
@EnableWebMvc
@AutoConfigureMockMvc(addFilters = false)
@SpringBootTest(classes = {MyController.class, MyConverter.class})
class TestController {
@Autowired
private FormattingConversionService conversionService;
@Autowired
MyConverter myConverter;
@BeforeEach
void setUp() {
conversionService.addConverter(entityConverter);
}
}
Upvotes: 0
Reputation: 3660
If anyone uses implements org.springframework.core.convert.converter.Converter<IN,OUT>
and if you are getting similar error while using mockMvc, please follow the below method.
@Autowired
YourConverter yourConverter;
/** Basic initialisation before unit test fires. */
@Before
public void setUp() {
FormattingConversionService formattingConversionService=new FormattingConversionService();
formattingConversionService.addConverter(yourConverter); //Here
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.standaloneSetup(getController())
.setConversionService(formattingConversionService) // Add it to mockito
.build();
}
Upvotes: 7
Reputation: 8297
The conversionService
is a mock.
So this:
conversionService.addConverter(new SessionStateConverter());
calls addConverter
on mock. This does nothing useful for you.
I believe you want to use real FormattingConversionService
: to do it you need to remove @Mock
annotation from conversionService
field and use a real instance of FormattingConversionService
instead:
private FormattingConversionService conversionService = new FormattingConversionService();
If you need to track invocations on real objects as you would do on mock check out : @Spy
Upvotes: 5