【问题标题】:Testing Process.Start?测试过程。开始?
【发布时间】:2008-12-08 12:18:53
【问题描述】:

我正在创建一个应用程序,它将管理外部实用程序的多个实例,为每个实例提供数据并获取结果。

但是当我为班级编写单元测试时,我遇到了一个问题。

如何测试目标方法在调用时是否实际启动了一个进程(通过属性设置)?

我试过了:

  • 让类执行外部进程,然后使用 GetProcessesByName 检查它是否已启动。
  • 使用输出重定向,例如使用大于号将某些内容回显到文件并测试其存在

我觉得发出代码和/或创建另一个 exe 来测试是多余的。

这是确切的方法:

public void Start()
{
    if (!_isRunning) {
        var startInfo = new ProcessStartInfo() {
            CreateNoWindow = true,
            UseShellExecute = true,

            FileName = _cmdLine,
            Arguments = _args
        };

        _process = Process.Start(startInfo);
        _isRunning = true;

    } else {
        throw new InvalidOperationException("Process already started");

    }
}

我想对它进行单元测试,以便如果没有运行 (_isRunning == false),则应该生成一个新进程。

我感到很难过,有没有一种优雅的方法来对外部进程实际启动进行单元测试?

【问题讨论】:

    标签: c# unit-testing process


    【解决方案1】:

    我会使用依赖注入并使用模拟或假类来解决这个问题。注意我使用的是实例方法而不是类方法。在您的常规代码中,您可以使用默认构造函数,它将为您创建一个进程。对于测试,您可以注入一个模拟或假进程,并简单地检查是否在模拟对象上调用了正确的方法,而根本不必实际启动一个进程。您需要调整它以考虑我省略的属性。前任。下面:

     public class UtilityManager
     {
          public Process UtilityProcess { get; private set; }
    
          private bool _isRunning;
    
          public UtilityManager() : this(null) {}
    
          public UtilityManager( Process process )
          {
              this. UtilityProcess = process ?? new Process();
              this._isRunning = false;
          }
    
          public void Start()
          {
              if (!_isRunning) {
              var startInfo = new ProcessStartInfo() {
                  CreateNoWindow = true,
                  UseShellExecute = true,
    
                  FileName = _cmdLine,
                  Arguments = _args
              };
    
              this.UtilityProcess.Start(startInfo);
              _isRunning = true;
    
          } else {
              throw new InvalidOperationException("Process already started");
          }
     }
    

    测试代码...

     [TestMethod]
     public void StartTest()
     {
          Process proc = new FakeProcess();  // May need to use a wrapper class
          UtilityManager manager = new UtilityManager( proc );
          manager.CommandLine = "command";
          ...
    
          manager.Start();
    
    
          Assert.IsTrue( proc.StartCalled );
          Assert.IsNotNull( proc.StartInfo );
          Assert.AreEqual( "command", proc.StartInfo.FileName );
          ...
     }
    

    【讨论】:

    • 太好了!...我忽略了 startInfo 分离部分...必须让我的头脑再嘲笑一些...谢谢!
    • 您可以将 public UtilityManager() : this(null) {} public UtilityManager( Process process ) 更改为 public UtilityManager( Process process = null ) 以获得更短的代码。
    • @Bomberlt 如果我希望通过反射访问它的工具可以使用默认构造函数,则不要这样做。
    • UtilityProcess如何调用Start()方法? UtilityProcess 是一个实例,Start() 是一个静态方法!!
    • @sushmitgos 这样使用:UtilityProcess.StartInfo = startInfo; UtilityProcess.Start();
    猜你喜欢
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 2014-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    • 2022-09-30
    相关资源
    最近更新 更多