英文:
Unit testing static method- GsonSerializer
问题
public String fetchEntity(Object retValue, Object[] args) {
String refDet = null;
List<Details> updatedDetails = null;
if (retValue != null && retValue instanceof List && ((List) retValue).stream()
.noneMatch((o -> !(o instanceof Details)))) {
updatedDetails = (List<Details>) retValue;
} else {
logger.warn("Error");
return null;
}
try {
refDet = GsonConverter.serialize(updatedDetails);
} catch (Exception e) {
logger.warn("Error updatedDetails");
}
return refDet;
}
这是具有静态方法的类:
class GsonConverter {
public static final Gson GSON = new GsonBuilder()
.registerTypeAdapter(DateTime.class, (JsonDeserializer<DateTime>) (dateTime, type, context) -> ISODateTimeFormat.dateTime().parseDateTime(dateTime.getAsString()))
.create();
public static String serialize(Object o) {
return GSON.toJson(o);
}
}
英文:
I need to junit test a piece of code, but the GsonConverter it calls from different class is in static method that i cannot change. I haven't a clue how to proceed as i cant mock it due to it being static.
public String fetchEntity(Object retValue, Object[] args) {
String refDet= null;
List<Details> updatedDetails = null;
if (retValue != null && retValue instanceof List && ((List) retValue).stream()
.noneMatch((o -> !(o instanceof Details)))) {
updatedDetails = (List<Details>) retValue;
} else {
logger.warn("Error");
return null;
}
try {
refDet= GsonConverter.serialize(updatedDetails );
} catch (Exception e) {
logger.warn("Error updatedDetails ");
}
return refDet;
}
Here is the class with static methods
class GsonConverter{
public static final Gson GSON = new GsonBuilder()
.registerTypeAdapter(DateTime.class, (JsonDeserializer<DateTime>) (dateTime, type, context) -> ISODateTimeFormat.dateTime().parseDateTime(dateTime.getAsString()))
.create();
public static String serialize(Object o) {
return GSON.toJson(o);
}
}
</details>
# 答案1
**得分**: 2
最简单的方法是将直接使用的GsonConverter隐藏在对象实例后面。也许可以这样做:
```java
interface JsonMapper {
String toJsonString(Object o);
}
class GsonJsonMapper implements JsonMapper {
String toJsonString(Object o) {
return GsonConverter.serialize(o);
}
}
现在在您的原始代码中,依赖于该接口(JsonMapper),但将其实例化为GsonJsonMapper(最好使用类似Guice或Spring这样的依赖注入框架)。
// 声明一个JsonMapper类型的实例
private JsonMapper mapper;
public String fetchEntity(Object retValue, Object[] args) {
// 跳过前面的部分...
try {
// 使用mapper
refDet = mapper.serialize(updatedDetails );
} catch (Exception e) {
logger.warn("Error updatedDetails ");
}
return refDet;
}
现在您有能力模拟JsonMapper接口。
您经常会遇到这种情况——不是为了可测试性而编写的代码通常必须更改以添加测试。这就是为什么许多开发人员会实践TDD,或者至少在编写新代码之后立即编写单元测试的原因。
英文:
The simplest thing would be to hide the direct use of GsonConverter behind an object instance. Perhaps something like:
interface JsonMapper {
String toJsonString(Object o);
}
class GsonJsonMapper implements JsonMapper {
String toJsonString(Object o) {
return GsonConverter.serialize(o);
}
}
Now in your original code, depend on the interface (JsonMapper) but instantiate it as an GsonJsonMapper (ideally using a dependency injection framework like Guice or Spring).
// declare an instance of type JsonMapper
private JsonMapper mapper;
public String fetchEntity(Object retValue, Object[] args) {
// skip the first part ...
try {
// use the mapper
refDet = mapper.serialize(updatedDetails );
} catch (Exception e) {
logger.warn("Error updatedDetails ");
}
return refDet;
}
Now you have the ability to mock out the JsonMapper interface.
You will often encounter this type of situation -- code that was not written to be testable often must change in order to add tests. Which is why many developers practice TDD, or at least write unit tests immediately after writing the new code.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论