Issue
I have spring boot mvc application and I use custom deserializer for my object. My custom deserializer class has constructor that get 1 parameter:
@JsonDeserialize(using = MyObjectDeserializer.class)
class MyObject {
. . .
}
@Component
class MyObjectDeserializer extends JsonDeserializer<MyObject> {
private AnotherObject anotherObject;
@Autowired
public MyObjectDeserializer(AnotherObject anotherObject) {
this.anotherObject = anotherObject;
}
...
}
When I run application all works well, so as I understand there is some "magic": some component creates objectMapper bean and beans for AnotherObject and MyObjectDeserializer beans. But in unit test this "magic" is absent:
@RunWith(SpringRunner.class)
public void MyObjectDeserTest {
@Autowired
private ObjectMapper objectMapper;
}
In tests objectMapper is null. How can I initialize objectMapper in unit that deserialize classes created correctly with dependencies?
Or may be there is another more correctly way to inject some object to the deserializer?
Solution
In tests objectMapper is null. How can I initialize objectMapper in unit that deserialize classes created correctly with dependencies?
It's simply because it's not able to inject a proper initialized bean at run time.
Using @SpringBootTest
annotation should suffice in your case.
@RunWith(SpringRunner.class) // not sure why you require this
@SpringBootTest
public void MyObjectDeserTest {
@Autowired
private ObjectMapper objectMapper;
}
Note that this would load the entire Application context and is a flaky way of testing.
Please consider using only source class of test i.e. MyObjectDeserializer
object when writing unit tests. Let the underlying dependencies be handled by Mocks.
Answered By - Manav Chhibber
Answer Checked By - Marilyn (JavaFixing Volunteer)