测试在 Clean 架构中做不止一件事的 Interactor 方法

Testing Interactor methods that do more than one thing in a Clean architecture

我一直在阅读有关单元测试和 Clean architecture 的文章,并试图实现涉及这两件事的东西。

据我了解,Clean 架构的结构使得可以对 Interactor 对象的方法进行单元测试。

但是当用例类似于 "Create a file which content is computed from some data in some format" 时,我会感到困惑,因为它不是单一的(文件内容的计算和文件的创建,两者都是 用例中)

这里有一些伪代码说明了我的情况:

/* We are in an Interactor (i.e. UseCaseObject)
 * This method 1)computes fileContent and 2)writes it into a file. 
 */
public void CreateFileFromData(someDataInSomeFormat) {
    var parsedData = SomeParser.Parse(someDataInSomeFormat);

    string fileContent = ???; 

    WriteFile(fileContent); 
}

我的问题如下:

  1. Interactor 中定义的方法必须是单一的吗? (如,只做一件事)
  2. 必须对交互器中定义的方法进行单元测试吗? (我看到一个函数,不管是不是单一的,作为一个可测试的单元,如果不正确请指正)
  3. 哪个 class 必须在 Clean 架构中计算文件内容?

您不知道计算数据的来源 "loaded",但例如假设将从另一个文件读取数据。

您的交互器将具有三个依赖项
- 读取文件
- 计算新文件的数据
- 写入文件

public class Interactor
{
    public Interactor(IReader reader, ICalculator calculator, IWriter writer)
    { }

    public void DoJob()
    {
        var data = reader.Read();
        var calculatedData = calculator.Calculate(data);
        writer.Write(calculatedData);
    }
}

通过这种方法,Interactor 将负责完成任务所需的 "combine" 个步骤。

您可以通过模拟所有依赖项来简单地测试 Interactor。

其中:
IReaderIWriter 网关
ICalculatorUseCase 的实现细节,被 Interactor

使用

Must a method defined in the Interactor be unitary ? (as in, do only one thing)

方法应该做一件事——执行与用例相关的任务。如果任务需要使用网关(外部资源)或任务太复杂以将其保持在一种方法中 - 您将引入所有必需的单元作为依赖项,交互者的责任将 "glue" 它们放在一起。

Must a method defined in the Interactor be unit-tested ? (I see a function, unitary or not, as a testable unit, please correct me if this is incorrect)

仅抽象网关(外部资源)- 然后您可以测试交互器的整个逻辑。如果您先编写测试 - 您将编写测试并且整个逻辑可以在一个函数中(它 could/should 是丑陋的意大利面条代码,它使测试通过)。然后,当您看到实施的全貌时,您可以通过将事情转移到专用的 classes.

来开始调动员工

Which class must hold the computation of fileContent in a Clean architecture ?

如果是简单的一行计算,可以是interactor。但是我更愿意引入dedicated class for computation 并将其作为依赖引入。虽然测试将保留在交互器和专用计算中 class 将通过交互器测试进行测试

Clean Architecture 的一个核心方面是所有应用程序业务逻辑都在 Interactor 方法中。这意味着您还希望将主要测试重点放在通常使用单元测试和低级别验收测试的交互器上。

在设计您的交互器方法时,您仍应遵循 SRP:更改的理由应该只有一个。 你也可以结合Interactors来跟随SRP。

如果文件内容的计算是您的应用程序业务逻辑,它应该在交互器方法中。

有关 Interactors 的更详细讨论,请查看我的 post:https://plainionist.github.io/Implementing-Clean-Architecture-UseCases/