1

下面给出的是我的产品代码本质和简化表示。这就像一个完成工作流程的算法。每个步骤(私有方法)都会导致数据库中的记录发生更改。甚至外部工具调用也会导致通过另一种回调反馈机制更新数据库。

void IWorkFlow.PerformBusinessWorkflowX(Input input) 
{

    PreparePreRequisiteData();

    DoTask_A();

    TriggerExternalToolTo_DoTask_B();   /* external tool invocation */
}

我的一位同事想为此编写一个集成测试用例,但不想包含外部工具调用。如果 BusinessWorkFlow 逻辑处于集成级别但不包括外部工具,他的目标是测试其余部分。不是使用模拟的单元测试,而是集成测试,他在其中验证数据库前后测试的状态。为了达到目的,他修改了这样的代码。

void IWorkFlow.PerformBusinessWorkflowX(Input input, bool isTriggerExternalTool) 
{

    PreparePreRequisiteData();

    DoTask_A();

    if(isTriggerExternalTool) 
    {
        TriggerExternalToolTo_DoTask_B();   /* external tool invocation */
    }
}

但是,我对这种重构风格不满意。由于外部工具的调用是业务工作流程中不可分割/不可分割的一部分,因此我宁愿不要将产品代码修改为具有指示工具调用是可选的布尔标志。

我认为更好的解决方案(但丑陋(?)因为它的性质)是坚持使用原始方法而不需要传入布尔标志依赖项。相反,决定调用该工具以支持嵌入在TriggerExternalToolTo_DoTask_B() 方法。或者甚至调用它 TryTriggerExternalToolTo_DoTask_B()。

就像是,

private void TryTriggerExternalToolTo_DoTask_B()
{
    //will be false for integration tests. Any other value then invoke. 
    if(ConfigurationManager.AppSettings["InvokeTool"] != "false") 
    {

    }
}

我也不赞成将 IWorkFlow.PerformBusinessWorkflowX(Input input) 方法分解为两部分(一部分执行前两个步骤,第二部分仅执行通过不同接口方法公开的工具调用),只是为了在产品代码方面具有灵活性并支持测试代码。也因为所有步骤都属于单个工作流程(算法)。

问题

1)我是否错误地说在产品代码中引入布尔标志只是为了支持测试可能不是最佳实践?(有些人告诉我,这就是可测试性设计。我希望这不是可测试性设计的真正含义)

2) 将调用逻辑推入 TryTriggerExternalToolTo_DoTask_B() 并依靠 appsetting 来救援的看似丑陋的解决方案是更好的解决方案吗?

3)看到我不想为了灵活性而分解方法(扩展接口),有没有更好的解决上述问题的方法?

PS - 如果我不了解,请纠正我并提供开放的技术建议。

4

2 回答 2

2

不,我不会仅仅为此修改原型。呃,我讨厌测试人员对我优雅的类设计嗤之以鼻。

处理这个问题的适当方法是注入一个执行外部函数的类。如果注入的类为空,则跳过它。这样,测试人员可以使用 AutoFac 或您正在使用的任何 DI 工具包配置他的测试;他可以将其打开、关闭,甚至替换他自己的 IExternalToolInvoker 类,该类仅检查输入(在我的示例中为a,bc)并确保它们是正确的。

class WorkflowExecutor : IWorkflow
{
    IExternalToolInvoker _invoker;

    public WorkflowExecutor(IExternalToolInvoker invoker)
    {
        _invoker = invoker;
    }

    public void Execute(IInput input)
    {
        PreparePrerequisiteData();
        DoTask_A();

        if (_invoker != null) invoker.TryTriggerExternalTool(a, b, c);
    }
}
于 2017-01-20T00:41:27.610 回答
0

我也喜欢@JohnWu 的回答。需要考虑的另一件事:测试人员的修改/请求可能表明您的班级做得太多。依赖注入解决方案将是一种将功能分开的方法。

于 2017-01-21T22:13:19.927 回答