2

ユニットテストについてさらに学ぶにつれて、この分野でよく知られている動作(相互作用)と状態検証のアプローチを理解するようになりました。

特定の操作を実行した後にシステムの状態を確認することは、私には論理的に思えます。

テスト対象のクラスと他のコンポーネントとの相互作用を検証することについても同じことが言えますか?私はまだ100%確信していません。

例えば:

public void DoSomething(IDependency dependency)
{
    // some code ...

    dependency.Method();

    dependency.Method2();

    // some more code ...
}

DoSomething()の現在の実装がMethod()とMethod2()を呼び出し、モックを使用してテスト可能であるという事実には、実際の価値がありますか?

これらの2つのメソッドの呼び出しは、DoSomething()の実装の詳細ではありませんか?

相互作用の検証は、状態ベースの検証と比較するとはるかに脆弱であり、カプセル化(この方法で隠されているものをテストする)も破られるようです。

4

2 に答える 2

3

仕様 (一部ではテストと呼ばれる) で特定の種類の対話が行われる必要がある場合は、これが事実であることを確認し、そのための単体テストも行う必要があります。たとえば、SUT がファイルを保存する必要がある場合は、おそらくそれIFileSystem.Save(...)が呼び出されたことを確認する必要があります。また、ファイルが存在する場合、SUT が新しいファイル名でそれを安全にする必要がある場合はIFileSystem.Save(...)、正しいファイル名で呼び出され、それが呼び出されたことを確認する必要がありますIFileSystem.Exists(...)。これは最高の相互作用テストです。

FakeItEasyを使用すると、次のようになります。

// arrange
var fileSystem = A.Fake<IFileSystem>();
A.CallTo(() => fileSystem.Exists("file.txt")).Returns(true);
A.CallTo(() => fileSystem.Exists("file1.txt")).Returns(false);
var sut = new SystemUnderTest(fileSystem);

// act
sut.DoSomething(); // do something that eventually saves file.txt

// assert
A.CallTo(() => fileSystem.Exists("file.txt")).MustHaveHappened();
A.CallTo(() => fileSystem.Exists("file1.txt")).MustHaveHappened();
A.CallTo(() => fileSystem.Save("file1.txt")).MustHaveHappened();
于 2013-03-13T21:21:39.633 に答える
0

ええと、あなたが の動作を確認したいのであればDoSomething(IDependency dependency)、依存関係が呼び出されていることを確実に確認したいと思います。

それがモックの典型的な目的です。で依存関係が正しく処理されていることを確認する必要がありますSuT。依存関係の実装の詳細に煩わされたくありません。

だから私は良いテストは次のようになります:

[Test]
public void DoSomething()
{
    var sut = new Whatever();
    var dependencyMock = MockRepository.GenerateMock<IDependency>();
    dependencyMock.Stub(() => mock.Method1()).Repeat = 1;
    dependencyMock.Stub(() => mock.Method2()).Repeat = 1;
    sut.DoSomething(dependencyMock);

    // verify that expected methods are being called
    dependencyMock.VerifyAllExpectations(); 

    // make some meaningful assert for sut.
    Assert. // ... etc
}

スタジオを開かずにこれを入力したことに注意してください。したがって、モジュロタイポはモジュロバグです:)。アイデアを提供するだけです。


機能を「接着」するだけの場合。クラスが他に何もせず、依存オブジェクトのメソッドを呼び出すように、その「コードの匂い」をリファクタリングする必要があるかどうかを調査する価値があるかもしれません。しかし、あなたが上で提供した例では、あなたはそれで大丈夫だと思います。

于 2013-03-13T21:21:29.463 に答える