外部EXEを開始するクラスのユニットテストの記述


9

EXEのリストを開始するために使用するC#クラスを作成しました(私のものではありません-実行する必要のあるサードパーティのEXE)。 。

追加、削除などの基本的なロジックをテストできます。EXEを保持する実際の作業が機能することを単体テストするにはどうすればよいですか?

私の最初の考えは、1秒後に自分自身を閉じるダミーEXEを起動し、それを使用してテストすることです。それは単体テストの領域外ですか?

回答:


12

私の最初の考えは、1秒後に自分自身を閉じるダミーEXEを起動し、それを使用してテストすることです。それは単体テストの領域外ですか?

これは良いテストですか?もちろん、作成します。それは本当の意味での「単体テスト」ですか?私はそうは思わない、私はこれを「システムテスト」またはそのようなものと呼ぶだろうが、それはテストをより価値のあるものにするわけではない。


9

それより高いレベルでモックアウトします。周りProcess.Start()にプロキシクラスを作成し、テストでそれを偽装して、入力を確認します。

public interface IProcessProxy
{
     ProcessInfo Start(string application, string[] arguments);
}

public class ProcessProxy : IProcessProxy
{
    public ProcessInfo Start(string application, string[] arguments)
    {
        return Process.Start(application, arguments);
    }
}

// You could use a mocking framework for this, but for the purposes
// of this example ...
public class FakeProcessProxy : IProcessProxy
{
    private string _expectedApplication;
    private string[] _expectedArguments;
    private ProcessInfo response;

    public FakeProxy(string expectedApplication, string[] expectedArguments, ProcessInfo response)
    {
         _expectedApplication = expectedApplication;
         _expectedArguments = expectedArguments;
    }

    public ProcessInfo Start(string application, string[] arguments)
    {
         // compare input to expectations and throw exception if not matching
         return _response;
    }
}

// You can also use an IoC framework to inject your IProcessProxy, but I won't.
public class ClassUnderTest
{
    public ClassUnderTest(IProcessProxy proxy)
    {
        _proxy = proxy;
    }

    public ClassUnderTest() : this(new ProcessProxy())
    {
    }

    public void MethodUnderTest()
    {
        // Do stuff

        ProcessInfo process = _proxy.Start(@"C:\Program Files\App\App.exe", new[] { "arg1", "arg2" });
        process.WaitForExit();

        if (process.ExitCode == 0)
        {
            // Act on success
        }
        else
        {
            // Act on failure
        }
    }   
}

アプリケーションコードでClassUnderTestを使用する必要がある場合は、デフォルトのコンストラクタを使用してください。テストでは、予想されるプロキシ開始パラメーターと偽のコンストラクターでのテスト結果を使用して、FakeProcessProxyを他のコンストラクターに渡します。


4

ユニットテストの哲学(unitに重点を置く)に厳密に従う場合、Exeファイルを作成するのではなく、クラスがインターフェイスを呼び出してそのプロセスを正しく生成および監視するかどうかをテストする必要があります。結局のところ、プロセスの処理を担当するライブラリではなく、クラスをテストしたいのです。

しかし、実用的な観点からは、1秒は少し長いようですが、アプローチは問題ありません。


1

私は似たようなことをしましたが、とだけ呼ばれましたping localhost。ビルドサーバーに実行可能ファイルを配置する手間を省きます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.