我试图将单元测试写入自定义反序列化器,该自解序列器使用带有@Autowired参数的构造函数实例化,而我的实体标有@JsonDeserialize。在我的集成测试中,它可以正常工作,其中MockMvc带来了spring服务器端。
但是,在调用objectMapper.readValue(…)的测试中,将实例化使用默认构造函数(不带参数)的反序列化程序的新实例。即使
@Bean
public MyDeserializer deserializer(ExternalObject externalObject)
实例化解串器的有线版本,实际调用仍传递给空的构造函数,并且上下文未填充。
我尝试手动实例化一个反序列化器实例并将其注册到ObjectMapper中,但是仅当我从我的实体类中删除@JsonDeserialize时,它才起作用(即使我在@Configuration类中执行相同的操作,也会破坏我的集成测试。)-看起来很相关对此:https : //github.com/FasterXML/jackson-
databind/issues/1300
我仍然可以直接测试调用deserializer.deserialize(…)的反序列化器行为,但是这种方法在非Deserializer单元测试的测试中对我不起作用…
UPD:下面的工作代码
import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import com.github.tomakehurst.wiremock.common.Json;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.json.JsonTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
import java.io.IOException;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@JsonTest
@RunWith(SpringRunner.class)
public class JacksonInjectExample {
private static final String JSON = "{\"field1\":\"value1\", \"field2\":123}";
public static class ExternalObject {
@Override
public String toString() {
return "MyExternalObject";
}
}
@JsonDeserialize(using = MyDeserializer.class)
public static class MyEntity {
public String field1;
public String field2;
public String name;
public MyEntity(ExternalObject eo) {
name = eo.toString();
}
@Override
public String toString() {
return name;
}
}
@Component
public static class MyDeserializer extends JsonDeserializer<MyEntity> {
@Autowired
private ExternalObject external;
public MyDeserializer() {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
public MyDeserializer(@JacksonInject final ExternalObject external) {
this.external = external;
}
@Override
public MyEntity deserialize(JsonParser p, DeserializationContext ctxt) throws IOException,
JsonProcessingException {
return new MyEntity(external);
}
}
@Configuration
public static class TestConfiguration {
@Bean
public ExternalObject externalObject() {
return new ExternalObject();
}
@Bean
public MyDeserializer deserializer(ExternalObject externalObject) {
return new MyDeserializer(externalObject);
}
}
@Test
public void main() throws IOException {
HandlerInstantiator hi = mock(HandlerInstantiator.class);
MyDeserializer deserializer = new MyDeserializer();
deserializer.external = new ExternalObject();
doReturn(deserializer).when(hi).deserializerInstance(any(), any(), eq(MyDeserializer.class));
final ObjectMapper mapper = Json.getObjectMapper();
mapper.setHandlerInstantiator(hi);
final MyEntity entity = mapper.readValue(JSON, MyEntity.class);
Assert.assertEquals("MyExternalObject", entity.name);
}
}
一个非常有趣的问题,使我想知道自动插入杰克逊解串器在弹簧应用程序中如何工作。使用的jackson工具似乎是HandlerInstantiator
interface,它是由spring配置到SpringHandlerInstantiator
实现的,该实现只是在应用程序上下文中查找类。
因此,从理论上讲,您可以ObjectMapper
使用自己的(模拟的)在单元测试中设置一个,HandlerInstantiator
从中返回一个准备好的实例deserializerInstance()
。返回null
其他方法似乎很好,或者当class参数不匹配时,这将导致jackson自行创建实例。
但是,我认为这不是对反序列化逻辑进行单元测试的好方法,因为ObjectMapper
设置必然与实际应用程序执行过程中使用的设置不同。使用JsonTest
Anton答案中建议将是一种更好的方法,因为您将获得与运行时相同的json配置。
我正在尝试编写一个单元测试到一个自定义反序列化器,该反序列化器是使用一个带有@了的构造函数来实例化的,并且我的实体标有@JsonDesri的。它在我的集成测试中工作得很好,其中MockMvc会带来Spring serverside。 然而,在调用objectMapper.read值(…)的测试中,使用不带参数的默认构造函数的反序列化器的新实例被实例化。即使 实例化有线版本的反序列化程序,实际调用仍
全部的 我在我的主要Spring Boot应用程序类中定制了,如下所示。 其中,是的扩展。我的POJO是用Jackson的注释的 我使用和注释通过HTTP公开了POJO。这很好,当我运行应用程序并访问endpoint时,会调用自定义过滤器。 现在我编写了一个集成测试,如下所示。 当我运行测试时,obj为null,我看到一个错误,没有配置FilterProvider 我做错了什么,如何纠正? 我的文
我有一个自定义任务定义来运行每个测试具有特殊设置的特定测试文件。我的任务定义如下: 现在,此设置中的一些测试是不可靠的,我尝试再次运行它们,如下所示: 我编写了一个测试类,第一次总是失败,第二次总是成功: 不幸的是,测试只执行一次,整个测试套件失败。我可以使用中所述的自定义规则成功运行测试https://stackoverflow.com/a/55178053/6059889 有没有办法将测试重试
我编写了以下来让Jackson将一个数组的整数序列化为JSON: 此处使用该类: 我想测试序列化程序的行为,并得出以下结论: 但是,不向写入任何内容。我做错了什么?
我正在使用Spring Boot创建一个访问数据库的简单web应用程序。通过在中设置属性,我利用了DataSource的自动配置功能。这一切都很出色,而且非常快--伟大的工作伙计们@Spring! 我公司的政策是不应该有明文密码。因此,我需要对进行加密。经过一番深入研究,我决定创建一个实现,该实现创建一个jasypt,如下所示: 然后,我用文件将其打包到它自己的jar中,如下所示: 当在maven
本机Spring Boot自动配置(例如one)也可以检测主类中声明的bean(例如注释的方法)。 如何对主类中声明的bean进行正确的bean检测? 编辑
我使用的是Spring Framework4.1.6版本,带有Spring web services,不带Spring Boot。为了学习这个框架,我正在编写一个REST API,并进行测试,以确保从命中一个endpoint收到的JSON响应是正确的。具体地说,我正在尝试调整的以使用“带下划线的小写”命名策略。 我正在使用Spring的博客中详细介绍的方法创建一个新的并将其添加到转换器列表中。具体
我正在为Python中的Robot Framework编写一个自定义测试库,我想这样导入它: 我把包含源代码的文件夹放在上,但我仍然收到错误: CustomLibrary类在初始化中定义。py文件,如AppiumLibrary中的: 我该如何解决这个问题,以便将其导入Robot框架?我希望将类定义保留在init文件中。