单元测试静态方法 – GsonSerializer

huangapple go评论131阅读模式
英文:

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&lt;Details&gt; updatedDetails = null;
    	if (retValue != null &amp;&amp; retValue instanceof List &amp;&amp; ((List) retValue).stream()
                .noneMatch((o -&gt; !(o instanceof Details)))) {
    		updatedDetails = (List&lt;Details&gt;) retValue;	
    	} else {
    		logger.warn(&quot;Error&quot;);
    		return null;	
    	}
    	try {
    		refDet= GsonConverter.serialize(updatedDetails );
		} catch (Exception e) {
			logger.warn(&quot;Error updatedDetails &quot;);	
		} 
    	return refDet;
    }

Here is the class with static methods

class GsonConverter{
public static final Gson GSON = new GsonBuilder()
 .registerTypeAdapter(DateTime.class, (JsonDeserializer&lt;DateTime&gt;) (dateTime, type, context) -&gt; 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(&quot;Error updatedDetails &quot;);   
  } 
  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.

huangapple
  • 本文由 发表于 2020年9月16日 00:03:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/63905751.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定