繁体   English   中英

如何在 c# Visual Studio 2019 中的单元测试方法中使用控制台或终端来显示 output 并接收用户的输入?

[英]How to use the console or terminal inside of a unit test method in c# visual studio 2019 to display output and receive input from user?

我正在尝试编写代码来提示用户并询问他们想要测试哪些测试文件(我需要能够测试进来的不同客户文件并且所有文件都以客户名称开头)。 然后,我想将与用户提供的文件相匹配的文件移动到一个文件夹,我创建的单元测试可以在其中抓取它们并对其运行测试。 即使调用 Console.writeLine() function 时,我也无法显示控制台(显然,我无法在控制台中输入任何内容以响应控制台上应该显示的内容)。

我尝试使用 [ClassInitialize] 标记并调用在此标记方法中提示用户的方法。 我还尝试在我的单元测试方法 ([TestMethod]) 的顶部调用这些相同的方法,但这也不起作用。 我知道 output 将在测试资源管理器中的“为此结果打开额外的 output”下,但这对我没有帮助。

    [TestMethod]
    public void CompareModels()
    {
        Console.WriteLine("Please enter customer that you want to test: ");
        var userInput = Console.ReadLine();
        var testFiles = Directory.GetFiles("my test file directory");
        foreach(var file in testFiles)
        {
            if(file.Contain(userInput)
                File.Move(file, "my in testing directory");
        }
    }

我希望控制台显示在第一行代码上,但它没有,并且程序在 console.ReadLine() 上永远等待,因为我无法在不会出现的控制台中输入任何输入。 我还想补充一点,如果用户在几秒钟内没有输入任何内容,那么测试将使用“测试中”目录中的文件运行。 因此,用户可以在不手动移动文件的情况下更改正在测试的客户,或者只需运行测试,他们将为他们完成所有工作。

正确的方法是将要测试的逻辑与 UI 隔离,如果可能的话,与物理数据源(文件系统、数据库)隔离。 如果我们注入一个文件服务的抽象,我们可以测试纯逻辑。 对于测试,我们可以提供一个测试假人。 您可以使用正确的参数测试 dummy 的方法是否被调用了预期的次数。 当然,如果您愿意为此设置测试文件夹和文件,您可以提供真正的文件服务。

public interface IFileService
{
    string[] GetFiles(string path);
    void Move(string sourceFileName, string destFileName);
}

注入服务的逻辑实现:

public class FileMover
{
    private readonly IFileService _fileService;

    public FileMover(IFileService fileService)
    {
        _fileService = fileService;
    }

    public void MoveFiles(string sourceDir, string destinationDir, string filterText)
    {
        string[] testFiles = _fileService.GetFiles(sourceDir);
        foreach (string file in testFiles) {
            if (file.Contains(filterText)) {
                _fileService.Move(file, destinationDir);
            }
        }
    }
}

您可以使用 mocking 框架来创建测试假人。 他们从您可以配置为执行操作的界面自动创建一个已检测的 class。 dummy 自动计算方法调用并注册它们的参数,返回您配置的内容等。

无控制台测试:

[TestMethod]
public void CompareModels()
{
    // Arrange
    IFileService fileService = Substitute.For<IFileService>();
    //TODO: setup fileService Dummy.

    var sut = new FileMover(fileService); // sut stands for Service Under Test.
    string sourceDir = @"C:\Test\Source";
    string destDir = @"C:\Test\Destination";
    string userInput = "abcd";

    // Act
    sut.MoveFiles(sourceDir, destDir, userInput);

    // Assert
    //TODO: test whether the fileService methods have been called as expected.
}

在真正的控制台应用程序中:

var fileService = new RealFileService();
var mover = new FileMover(fileService);

Console.WriteLine("Please enter customer that you want to test: ");
string userInput = Console.ReadLine();
mover.MoveFiles("my test file directory", "my in testing directory", userInput);

因此,如果您这样做,您将需要使用依赖注入容器。 这需要您通过接口定义所有服务。

public interface IFileMover
{
    void MoveFiles(string sourceDir, string destinationDir, string filterText);
}

public class FileMover : IFileMover
{
    ...
}

设置 DI 容器:

var diContainer = new SomeDependencyInjectionContainer();
diContainer.Register<IFileService, RealFileService>();
diContainer.Register<IFileMover, FileMover>();

DI 容器自动识别并创建它必须通过构造函数注入的服务。 所以你可以简单地创建一个文件移动器

var mover = diContainer.Resolve<IFileMover>();

将自动注入RealFileService

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM