簡體   English   中英

如何使用AutofacContrib.NSubstitute監視被測類

[英]How to spy the class under test with AutofacContrib.NSubstitute

我正在使用NSpec框架,AutofacContrib.NSubstitute v3.3.2.0,NSubstitute v1.7.0.0(目前最新為1.8.2)的類庫項目中運行單元測試。

測試中類”實例是使用AutoSubstitute ,以便自動模擬其所需的所有依賴項。

AutoSubstitute autoSubstitute = new AutoSubstitute();

MainPanelViewModel viewModel = autoSubstitute.Resolve<MainPanelViewModel>();

如果工作正常,則我的“待測類”有時會使用一些特定的輸入參數來調用其基類方法之一(該基類不在我的控制范圍內):

// ...
base.ActivateItem(nextScreen);
// ...

因此,出於測試期望,我需要檢查(間諜)實例是否調用基本方法:

viewModel.Received().ActivateItem(Arg.Any<SomeSpecificScreenType>());

這就是問題所在:當我嘗試執行此操作時,NSubstitute在運行時抱怨我只能對使用Substitute.For<>()創建的對象運行Received() Substitute.For<>() 我還快速檢查了AutofacContrib.NSubstitute源代碼,但找不到通過自動模擬獲取實例的方法,同時又以某種方式包裝在間諜對象或類似對象中。

我還認為Substitute.ForPartsOf<>()可能會有所幫助,但是NSubstitute v1.7.0中似乎找不到該方法。

為了完整起見,這里是NSubstitute完整錯誤:

NSubstitute擴展方法(如.Received())只能在使用Substitute.For()和相關方法創建的對象上調用。

因此,實際的問題尚未真正解決:只是問題本身消失了。

為了檢查正確的行為,我記得我也可以使用基類的ActiveItem公共屬性,因此我停止使用Receive()並返回簡單的值比較。

不過,為了將來參考,我還沒有找到使用這些庫監視被測類的方法。 我知道應該避免監視被測類,但是與許多事情一樣,有時您需要這樣做。

HTH

為了完整起見,我做了一些與NSubstitute與部分替代試驗ForPartsOf

ForPartsOf工作方式實質上是定義一個新類,該類繼承自您用作模板的類。 這限制了virtual框架可以攔截定義為abstractvirtual 如果要使用自己的類從類中繼承,則修改類的行為也有同樣的限制。

利用這些信息,讓我們看看您的問題。 您想攔截此呼叫:

base.ActivateItem(nextScreen);

因此,由於上述限制,為了使您能夠攔截對ActivateItem的調用,必須在基類中將該方法標記為virtual 如果不是的話,還有什么可以在不改變應用程序的結構做。

如果該方法被標記為virtual ,那么您可以使用NSubstitute對其進行攔截, 但是只有在調用NSubstituted實現的情況下才可以進行攔截。 這可以通過常規方法分派進行工作,因為在調用虛擬方法時,將調用虛擬方法的最高級別實現(由NSubstititute提供)。 但是,當您通過base引用調用方法時,該方法不起作用。

因此,盡管您可以截取以下內容:

ActivateItem(nextScreen)

您根本無法截獲:

base.ActivateItem(nextScreen);

您在代碼中使用base.ActivateItem的事實表明,被測類具有您自己不想調用的方法的實現,因此,使用當前的工具,您將無法實現您想要的方法做。 這就是為什么您找到一種解決方法是一件好事的原因。

您與大多數其他模擬框架(包括Moq)處於同一情況。 TypeMock是一個例外,它使用完全不同的方式來截獲方法調用,這意味着它可以執行其他框架根本做不到的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM