如何在单个测试中同时执行多个断言
前言
雖然,推薦做法是每次測(cè)試只斷言一件事,但是,在實(shí)際工作中,我們可能需要對(duì)同一個(gè)對(duì)象同時(shí)執(zhí)行多個(gè)斷言。
例如,微軟官方示例項(xiàng)目eShopOnContainers有一個(gè)測(cè)試用例的實(shí)現(xiàn)代碼如下:
[Fact] public?async?Task?Add_to_cart_success() {//Arrangevar?fakeCatalogItem?=?GetFakeCatalogItem();_basketServiceMock.Setup(x?=>?x.AddItemToBasket(It.IsAny<ApplicationUser>(),?It.IsAny<Int32>())).Returns(Task.FromResult(1));//Actvar?orderController?=?new?CartController(_basketServiceMock.Object,?_catalogServiceMock.Object,?_identityParserMock.Object);orderController.ControllerContext.HttpContext?=?_contextMock.Object;var?actionResult?=?await?orderController.AddToCart(fakeCatalogItem);//AssertAssert.Equal("Catalog",?redirectToActionResult.ControllerName);Assert.Equal("Index",?redirectToActionResult.ActionName); }如果我們將所有斷言都改成必定失敗:
//Assert Assert.Equal("WrongCatalog",?redirectToActionResult.ControllerName); Assert.Equal("WrongIndex",?redirectToActionResult.ActionName);但運(yùn)行測(cè)試時(shí),只會(huì)提示第一個(gè)失敗的斷言:
在這種情況下,一個(gè)個(gè)斷言去驗(yàn)證并修正比較耗時(shí)。
如果同時(shí)能夠看到所有失敗的斷言則更加有幫助。
手工實(shí)現(xiàn)
查看`Assert.Equal`的實(shí)現(xiàn)代碼[1],它是通過(guò)拋出EqualException異常來(lái)表明斷言失敗:
public?static?void?Equal<T>(T?expected,?T?actual,?IEqualityComparer<T>?comparer) {GuardArgumentNotNull(nameof(comparer),?comparer);var?expectedAsIEnum?=?expected?as?IEnumerable;var?actualAsIEnum?=?actual?as?IEnumerable;//?If?both?are?IEnumerable?(or?null),?see?if?we?got?an?AssertEqualityComparer<T>,?so?that//?we?can?invoke?it?to?get?the?mismatched?index.if?((expectedAsIEnum?!=?null?&&?(actual?==?null?||?actualAsIEnum?!=?null))?||(actualAsIEnum?!=?null?&&?expected?==?null)){var?aec?=?comparer?as?AssertEqualityComparer<T>;int??mismatchedIndex;if?(aec?!=?null?&&?!aec.Equals(expected,?actual,?out?mismatchedIndex)){if?(mismatchedIndex.HasValue)throw?EqualException.FromEnumerable(expectedAsIEnum,?actualAsIEnum,?mismatchedIndex.Value);elsethrow?new?EqualException(expected,?actual);}}if?(!comparer.Equals(expected,?actual))throw?new?EqualException(expected,?actual); }而所有斷言異常都繼承自基類(lèi)XunitException:
因此,我們可以捕獲每個(gè)斷言的異常,然后將多個(gè)異常添加到集合中,在測(cè)試結(jié)束時(shí)再拋出:
這里雖然列出了所有失敗斷言,但是所有錯(cuò)誤顯示了2遍,而且我們必須為測(cè)試編寫(xiě)大量的try-catch代碼。
有不有更好的方法呢?!
FluentAssertions
FluentAssertions是一組.NET擴(kuò)展方法,允許用更自然的語(yǔ)法去驗(yàn)證斷言。
引用Nuget包FluentAssertions,示例的斷言可以修改成如下格式:
redirectToActionResult.ControllerName.Should().Be("WrongCatalog"); redirectToActionResult.ActionName.Should().Be("WrongIndex");除此之外,還可以將多個(gè)斷言放到一個(gè)AssertionScope中,以便FluentAssertions在所有失敗的范圍末尾拋出一個(gè)異常:
using?(new?FluentAssertions.Execution.AssertionScope()) {redirectToActionResult.ControllerName.Should().Be("WrongCatalog");redirectToActionResult.ActionName.Should().Be("WrongIndex"); }結(jié)論
有時(shí),將多個(gè)斷言組合在一起測(cè)試是有意義的。
在這種情況下,可以使用FluentAssertions的AssertionScope來(lái)編寫(xiě)此類(lèi)測(cè)試。
如果你覺(jué)得這篇文章對(duì)你有所啟發(fā),請(qǐng)關(guān)注我的個(gè)人公眾號(hào)”My IO“
參考資料
[1]
Assert.Equal的實(shí)現(xiàn)代碼: https://github.com/xunit/assert.xunit/blob/main/EqualityAsserts.cs#L78
總結(jié)
以上是生活随笔為你收集整理的如何在单个测试中同时执行多个断言的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 探索 dotnet core 为何在 W
- 下一篇: ASP.NET Core 中是否有 Po