首页 > 解决方案 > 由于我想模拟的接口,apache bean 无法序列化

问题描述

无法序列化 DoFnWithExecutionInformation{doFn=com.orderly.dataflow.RosterFileReader@60ec7684, mainOutputTag=Tag, sideInputMapping={}, schemaInformation=DoFnSchemaInformation{elementConverters=[]}} java.lang.IllegalArgumentException:无法序列化 DoFnWithExecutionInformation{doFn=com .orderly.dataflow.RosterFileReader@60ec7684,mainOutputTag=Tag,sideInputMapping={},schemaInformation=DoFnSchemaInformation{elementConverters=[]}}

我不确定这是可能的。我在 apache Beam 中理解,这些函数必须是可序列化的以进行横向扩展,但在测试期间我也想模拟我们从哪里读取。

是否有某种上下文或我可以创建的东西来注入可模拟以供阅读的界面?

这是我的代码

public class RosterFileReader extends DoFn<String, PractitionerStandardOutputDto> {

    private static final Logger log = LoggerFactory.getLogger(RosterFileReader.class);

    private final String projectId;
    private GCPBucketStorage storage;

    public RosterFileReader(String projectId, GCPBucketStorage storage) {

我想知道是否有可以发送的上下文?GCPBucketStorage.java 是我们的 API,因为 googles 不是那么可模拟的。这样,我们就可以完全控制抛出异常和测试恢复以及其他场景。

编辑:我愿意接受这样的代码

if(isRunningLocally) {
     storage = new MockStorage();
} else { 
     storage = new GCPBucketStorageImpl();
}

在生产代码中使用这样的测试代码基本上有点糟糕,但是这个 END to END 测试已经发现了错误!!!!!!人们正在做的单元测试中遗漏的错误。我们通常不进行单类或单元测试,只进行 twitter 所称的功能测试,因为它允许在不涉及测试的情况下进行大量重构 -> https://blog.twitter.com/engineering/en_us/topics/insights/2017/the-测试-renaissance.html

我猜我可以使用静态字段进入 Mock(再次,我讨厌这样做,但这个测试非常有价值,真正端到端)

编辑 2:序列化是否像 hadoop 一样,您必须定义要与主 jar 一起部署的类?也许我只需要一个文档来使 GCPStorage 和 GCPBucketStorageImpl 可序列化(还有 MockStorage 也很可能因为它在生产代码中:( ) -> if..else 在我们发现的集成错误中是完全值得的 pre-CI 所以人们永远不会破坏 master 上的代码。

编辑3:这看起来很有希望-> https://gist.github.com/jlewi/f1cd323dc88bd58601ef 尝试后将更新帖子。

谢谢,院长

标签: apache-beamapache-beam-io

解决方案


实际上,只是使接口可序列化似乎在测试中工作(尚未在生产中测试)以及生产代码中的最后一行是丑陋的(我想知道我是否可以注入它)->

在此处输入图像描述

是的,在生产中拥有测试代码非常难看:(。值得注意的是,我没有注入接口,而是注入 GCPBucketStorageImpl.java (我们的产品实现),然后传入模拟(它是产品类的子类<--- - 这样做是为了让我们对将生产类修改为不可序列化的人进行测试验证,在这种情况下我们不会发现问题。


推荐阅读