有没有办法在 5.0.0 之后覆盖 io.cucumber.junit.Cucumber.java 中的 getDescription()?

Is there a way to override getDescription() in io.cucumber.junit.Cucumber.java after 5.0.0?

我正在尝试将现有项目从 3.0.2 升级到 5.5.0。该项目在 Cucumber.java 运行器 class 中自定义实现了 getDescription(),并且必须维护该功能,因为它依赖于其他项目。 JUnit 版本是 4.12.

在 3.0.2 中,Cucumber.java runner class 在 cucumber.api.junit.Cucumber 中被定义为

public class Cucumber extends ParentRunner<FeatureRunner>

这使得自定义运行程序非常简单:

public class DescriptiveCucumberRunner extends Cucumber
{
    public DescriptiveCucumberRunner(Class<?> testClass) throws InitializationError, IOException
    {
        super(testClass);
    }

    @Override
    public Description getDescription()
    {
        String text = "Cucumber tests running on " + new Date();
        Description originalDescription = super.getDescription();
        Description newDescription = originalDescription.childlessCopy();
        newDescription.addChild(Description.createSuiteDescription(text));

        for(Description childDescription : originalDescription.getChildren())
        {
            newDescription.getChildren().get(0).addChild(childDescription);
        }
        return newDescription;
    }
}

在 5.0.0 中,Cucumber.java runner class 被移动到 io.cucumber.junit.Cucumber 并且定义被更改为

public final class Cucumber extends ParentRunner<ParentRunner<?>>

所以我不能再延长了。

我试过扩展 org.junit.runners.ParentRunner

public class DescriptiveCucumberRunner extends ParentRunner<Cucumber>

并与委托聚合,但由于 Cucumber.java 的方法受到保护,我基本上必须复制整个 class 以保留当前功能,这并不是真正的解决方案全部。我可以使用反射来调用 Cucumber.java 中定义的方法,但这似乎也不是很干净。

有谁知道如何在不需要更改其他项目的情况下做到这一点?也许有一种我没有注意到的用 Cucumber 来做的方法?希望我只是错过了一个明显的解决方案,但到目前为止我还是一片空白。

通常使用组合优于继承。因此,与其扩展现有的 Cucumber runner class,不如考虑实现自己的 runner class,它有一个 Cucumber runner 的实例作为其子项之一。

package com.example;

import io.cucumber.junit.Cucumber;
import org.junit.runner.Description;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.ParentRunner;
import org.junit.runners.model.InitializationError;

import java.util.ArrayList;
import java.util.List;

public class MyCustomRunner extends ParentRunner<Cucumber> {

    private final List<Cucumber> children = new ArrayList<>(1);

    protected MyCustomRunner(Class<?> testClass) throws InitializationError {
        super(testClass);
        this.children.add(new Cucumber(testClass));
    }

    @Override
    public Description getDescription() {
        return // your custom description;
    }

    @Override
    protected List<Cucumber> getChildren() {
        return children;
    }

    @Override
    protected Description describeChild(Cucumber child) {
        return child.getDescription();
    }

    @Override
    protected void runChild(Cucumber cucumber, RunNotifier runNotifier) {
        cucumber.run(runNotifier);
    }
}