Testing Process.Start?

本小妞迷上赌 提交于 2020-01-31 04:30:25

问题


I am creating an application that will manage multiple instances of an external utility, supplying each with data and fetching results.

But as I am writing unit tests for the class I came upon a problem.

How do test that the target method actually starts a process (set via a property) when called?

I have tried:

  • Make the class execute an external process and then use GetProcessesByName to check if it has started.
  • Use output redirection, e.g. using the greater-than sign to echo something to a file and test its existence

I feel like emitting code and/or creating yet another exe to test is overkill.

This is the exact method:

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");

    }
}

I want to unit-test it so that if nothing is running (_isRunning == false), a new process should be spawned.

I feel stumped, is there an elegant way to unit-test that an external process actually starts?


回答1:


I would approach this using dependency injection and using a mock or fake class. Note I'm using the instance method for start instead of the class method. In your regular code, you can use the default constructor and it will create a process for you. For testing you can inject a mock or fake process and simply check that the proper methods are called on your mock object and never have to actually start a process at all. You'll need to adjust this to take account of the properties I've omitted. Ex. below:

 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");
      }
 }

Test code...

 [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 );
      ...
 }


来源:https://stackoverflow.com/questions/349336/testing-process-start

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!