日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

与protected成员有关的单元测试方式

發布時間:2023/12/10 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 与protected成员有关的单元测试方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是一篇簡單的文章,討論了單元測試中遇到protected成員的應對方案。此外,在文章最后也希望和大家討論一下某個特殊的情況下的處理方法。

protected是一個有趣而有用的修飾符,它把方法的訪問成員嚴格限制在自身或自己的子類身上。換句話說,在使用過程中,protected成員對外部是開放的(因為其他類可以通過繼承來使用該成員),又是封閉的(不是自身或子類的一切成員都無法訪問)。而對于單元測試來說,protected成員又是尷尬的,因為它的“開放”意味著我們必須對它進行單元測試,而“封閉”又阻礙了我們在單元測試中涉及protected成員。

測試protected方法

現在有一個類,其中包含一個protected方法:

public class SomeClass {protected int SomeMethod(string arg) { ... } }

如果我們需要對這個protected方法進行單元測試,可以在測試代碼中準備一個輔助類型:

public class SomeClassForTest : SomeClass {public int PublicSomeMethod(string arg){return this.SomeMethod(arg);} }

于是在單元測試中,便可以通過調用PublicSomeMethod來測試基類的SomeMethod方法:

var testClass = new SomeClassForTest(); var result = testClass.PublicSomeMethod(null); Assert.Equal(0, result);

非常簡單。

如果您覺得麻煩,也可以將SomeClass類中的SomeMethod方法改為protected internal,這樣便可以在InternalVisibleTo的測試程序集中使用了。不過,我覺得為單元測試而改變成員的訪問級別不是一個合適的做法。

對protected方法進行Mock

現在有一個類,其中有一個protected方法:

public class SomeClass {protected virtual int SomeMethod(string arg) { ... } }

并且,某個被測試的方法接受SomeClass作為參數。雖然被測試的方法不會直接調用SomeMethod方法,但是SomeMethod的實現會影響到公開接口的表現形式。于是,我們需要對SomeMethod進行Mock或Stub。為此,我們同樣需要準備一個輔助類型:

public class MockSomeClass : SomeClass {protected override int SomeMethod(string arg){return this.PublicSomeMethod(arg);}public virtual int PublicSomeMethod(string arg){return base.SomeMethod(arg);} }

在MockSomeClass中,我們覆蓋了基類的SomeMethod實現,使它調用了子類中公開的PublicSomeMethod方法,而PublicSomeMethod內部又調用了基類的SomeMethod方法。因此,如果您不去進行任何處理,那么MockSomeClass會保持SomeMethod的實現不變。而如果您需要對SomeMethod進行Mock或Stub的時候,便可以從PublicSomeMethod下手:

Mock<MockSomeClass> mockSomeClass = new Mock<MockSomeClass>() { CallBase = true }; mockSomeClass.Setup(c => c.PublicSomeMethod("123")).Returns(123);DoSomeTest(mockSomeClass.Object); // use the mock object

也很容易。

為了可測試性

值得注意的是,為了“可測試性”,第二部分中的protected方法必須是virtual的,因為我們需要在子類中進行override。同理,Mock框架能夠輔助的方法也必須是virtual的,即使是一個public方法。那么,您覺得這是為了可測試性而做出的讓步嗎?或者換句話說,您覺得,一個不可以override的protected方法,但是會影響到其他公開接口的功能,這是不是一個合理的設計呢?如果這是一個合理的設計,又不想作出這樣的讓步……我們又該怎么做呢?

關于這點,我有自己的想法,不過還是想先聽一下您的意見。

總結

以上是生活随笔為你收集整理的与protected成员有关的单元测试方式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。