1

最近、私は単体テストを改善しようとしていますが、UT の「ルール」の 1 つで、本当に混乱しているのは「テストごとに 1 つのアサート」です。

このテストのアサートに関して、MS が正しいことをしたと人々が考えているかどうかを知りたいです (モックの欠如などは無視してください)。私の現在の理解に基づくと、この例では、(1 回の呼び出しと複数のアサートではなく) テストする必要があるオブジェクト プロパティごとに 1 回の作成呼び出しを実際に実行する必要があります。この仮定は正しいですか?

以下から取得した方法: http://msdn.microsoft.com/en-us/vs2010trainingcourse_aspnetmvc3testing_topic4

[TestMethod()]
    [DeploymentItem("MvcMusicStore.mdf")]
    [DeploymentItem("MvcMusicStore_log.ldf")]
    public void CreateTest()
    {
            using (TransactionScope ts = new TransactionScope())
            {
                StoreManagerController target = new StoreManagerController();
                Album album = new Album()
                {
                    GenreId = 1,
                    ArtistId = 1,
                    Title = "New Album",
                    Price = 10,
                    AlbumArtUrl = "/Content/Images/placeholder.gif"
                };
                ActionResult actual;
                actual = target.Create(album);
                Assert.IsTrue(album.AlbumId != 0);
                MusicStoreEntities storeDB = new MusicStoreEntities();
                var newAlbum = storeDB.Albums.SingleOrDefault(a => a.AlbumId == album.AlbumId);
                Assert.AreEqual(album.GenreId, newAlbum.GenreId);
                Assert.AreEqual(album.ArtistId, newAlbum.ArtistId);
                Assert.AreEqual(album.Title, newAlbum.Title);
                Assert.AreEqual(album.Price, newAlbum.Price);
                Assert.AreEqual(album.AlbumArtUrl, newAlbum.AlbumArtUrl);
            }
    }

バージョンごとに次のようになります (アルバム オブジェクトのプロパティごとに複製されます)

    [TestMethod()]
    public void CreateTest_AlbumUrl()
    {
        // ** Arrange
        var storeDB = new Mock<MusicStoreEntities>()

        // Some code to setup the mocked store would go here

        StoreManagerController target = new StoreManagerController(storeDB);
        Album album = new Album()
           {
             GenreId = 1,
             ArtistId = 1,
             Title = "New Album",
             Price = 10,
             AlbumArtUrl = "/Content/Images/placeholder.gif"
            };

        // ** Act
        actual = target.Create(album);                      
        var newAlbum = storeDB.Albums.SingleOrDefault(a => a.AlbumId == album.AlbumId);

        // ** Assert
        Assert.AreEqual(album.AlbumArtUrl, newAlbum.AlbumArtUrl);
}
4

3 に答える 3

6

このルールは誤解されがちです。それは(コード/Assert呼び出しの行のように)単一のアサーションではなく、単一の概念を検証することです。この場合、Microsoftはアルバムが正しく追加されたことを確認します-アルバムはここでは単一の概念です。

ロイ・オシェロブはそれを非常に簡単な言葉で表現しています

私のガイドラインは通常、テストごとに1つの論理概念をテストすることです。同じオブジェクトに複数のアサートを設定できます。それらは通常、テストされているのと同じ概念になります。

于 2012-04-11T10:28:11.637 に答える
2

That should not be a hard rule, at most a rule of thumb. IMHO in many cases it is simpler and easier to put multiple asserts into a single test.

One should test a single story / case in each test, but this may well require multiple asserts to verify. IMHO it is overkill to create multiple nearly identical tests only to satisfy a "rule". But this is just my personal opinion. I prefer being pragmatic over adhering to book rules.

于 2012-04-11T10:24:19.003 に答える
0

そのルールを文字通りとるべきではありません。テストごとに1つの動作のみをアサートする必要がありますが、1つの動作のみAssertをアサートするために複数の呼び出しが必要になる場合があります。

この場合、テスト中の動作は、提供された情報を使用してアルバムが作成されているようです。

于 2012-04-11T10:26:20.597 に答える