如何使用Java对自定义日期反序列化器进行单元测试
我刚开始学习单元测试 我想对自定义日期反序列化器进行单元测试,如下所示: CustomDateDeserializer.java如何使用Java对自定义日期反序列化器进行单元测试,java,unit-testing,Java,Unit Testing,我刚开始学习单元测试 我想对自定义日期反序列化器进行单元测试,如下所示: CustomDateDeserializer.java import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterx
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 java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public class CustomDateDeserializer extends JsonDeserializer {
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Long toParse = p.getLongValue();
SimpleDateFormat format = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");
format.setTimeZone(TimeZone.getTimeZone("GMT+1"));
String formattedActualDate = format.format(new Date(toParse));
return formattedActualDate;
}
}
最好的测试方法是什么?
非常感谢您的建议。如果我理解得很好,您有一个JsonParser,您可以从中提取一个long并将其转换为可读的日期 首先,不要使用
Date
和SimpleDateFormat
:它们已经过时了,java.time
API比它们好得多。这就是我要用的
您需要的是模拟参数。JsonParser
和DeserializationContext
都是抽象类,因此很容易模拟它们
为了模拟,我们使用Mockito或Powermock等库
对于下面的示例,我使用了Mockito
CustomDateDeserializer deserializer;
JsonParser parser;
DeserializationContext context;
@BeforeEach
void setup() {
deserializer = new CustomDateDeserializer();
parser = mock(JsonParser.class);
context = mock(DeserializationContext.class);
}
@Test
void testDeserialize() {
when(parser.getLongValue()).thenReturn(12L*60*60*1000); // 1970-01-01T12:00:00.000Z
String result = deserializer.deserialize(parser, context);
assertEquals("01 Jan 1970 11:00:00 GMT+1");
}
但是您的实现使用了不推荐的API。。。您应该改用java.time。另外,请注意,Java允许您使返回类型比重写的方法更具体,因此让我们也重写您的方法:
class CustomDateDeserializer extends JsonDeserializer {
static final ZoneOffset ZONE_OFFSET = ZoneOffset.of("UTC+01:00");
static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd MMM yyyy HH:mm:ss z");
@Override
// Note the return-type is String, not Object
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Instant instant = Instant.ofEpochMilli(p.getLongValue());
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZONE_OFFSET);
return dateTime.format(FORMATTER);
}
}
嗨,非常感谢你的回答。在
LocalDateTime-dateTime=LocalDateTime.ofEpoch(instant,ZONE\u OFFSET)中使用您的代码进行反序列化时,我有一个问题
ofEpoch函数带红色下划线,我无法使用它。你知道为什么吗?我还使用用于自定义反序列化类的导入更新了我的代码。@user9347049抱歉,这是我的一个错误。您必须使用LocalDateTime.ofInstant
而不是LocalDateTime.ofEpoch
,这是我的错误。谢谢。当我尝试用stringresult=deserializer.deserialize(解析器,上下文)实现代码prom测试部分时,还有一个问题代码>带红色下划线,表示:所需类型:提供的字符串:对象代码>资产质量(“1970年1月1日11:00:00 GMT+1”);`部分错误:无法解析方法“assertEquals(java.lang.String)”
为什么?baeldung.com上的解释通常是有效的。但是他们的导航是次标准的,所以尝试搜索“junit baeldung”或任何主题,然后搜索“baeldung”,你会找到你大部分问题的答案。(你要知道,我和他们没有关系,我只是觉得他们做的很好。)我读了很多。好的,谢谢你!谢谢您的回答:)(1)不要使用Date
和SimpeDateFOrmat
。它们设计拙劣,早已过时。(2) 转向面向对象。不要用字符串表示日期和时间。使用即时
。(3) 不要使用GMT偏移量,假装它是一个时区。使用适当的时区ID,例如非洲/阿尔及尔或非洲/突尼斯。