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:
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?
Tests start at the unit level with developers performing unit tests. Then, the QA team runs tests at API and UI levels. Manual tests are run in accordance with previously designed test cases. All bugs detected are submitted in a defect tracking system.
Start(ProcessStartInfo)Starts the process resource that is specified by the parameter containing process start information (for example, the file name of the process to start) and associates the resource with a new Process component.
There are four main stages of testing that need to be completed before a program can be cleared for use: unit testing, integration testing, system testing, and acceptance testing.
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 );
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With