這是一篇簡單的文章,討論了單元測試中遇到protected成員的應對方案。此外,在文章最後也希望和大家討論一下某個特殊的情況下的處理方法。
protected是乙個有趣而有用的修飾符,它把方法的訪問成員嚴格限制在自身或自己的子類身上。換句話說,在使用過程中,protected成員對外部是開放的(因為其他類可以通過繼承來使用該成員),又是封閉的(不是自身或子類的一切成員都無法訪問)。而對於單元測試來說,protected成員又是尷尬的,因為它的「開放」意味著我們必須對它進行單元測試,而「封閉」又阻礙了我們在單元測試中涉及protected成員。
現在有乙個類,其中包含乙個protected方法:
public classsomeclass
}
如果我們需要對這個protected方法進行單元測試,可以在測試**中準備乙個輔助型別:
public classsomeclassfortest : someclass
}
於是在單元測試中,便可以通過呼叫publicsomemethod來測試基類的somemethod方法:
var testclass = newsomeclassfortest();
var result = testclass.publicsomemethod(null);
assert.equal(0, result);
非常簡單。
如果您覺得麻煩,也可以將someclass類中的somemethod方法改為protected internal,這樣便可以在internalvisibleto的測試程式集中使用了。不過,我覺得為單元測試而改變成員的訪問級別不是乙個合適的做法。
現在有乙個類,其中有乙個protected方法:
public classsomeclass
}
並且,某個被測試的方法接受someclass作為引數。雖然被測試的方法不會直接呼叫somemethod方法,但是somemethod的實現會影響到公開介面的表現形式。於是,我們需要對somemethod進行mock或stub。為此,我們同樣需要準備乙個輔助型別:
public classmocksomeclass : someclass
public virtual int publicsomemethod(string arg)
}
在mocksomeclass中,我們覆蓋了基類的somemethod實現,使它呼叫了子類中公開的publicsomemethod方法,而publicsomemethod內部又呼叫了基類的somemethod方法。因此,如果您不去進行任何處理,那麼mocksomeclass會保持somemethod的實現不變。而如果您需要對somemethod進行mock或stub的時候,便可以從publicsomemethod下手:
mockmocksomeclass = new
mock
() ;
mocksomeclass.setup(c => c.publicsomemethod("123")).returns(123);
dosometest(mocksomeclass.object); // use the mock object
也很容易。
值得注意的是,為了「可測試性」,第二部分中的protected方法必須是virtual的,因為我們需要在子類中進行override。同理,mock框架能夠輔助的方法也必須是virtual的,即使是乙個public方法。那麼,您覺得這是為了可測試性而做出的讓步嗎?或者換句話說,您覺得,乙個不可以override的protected方法,但是會影響到其他公開介面的功能,這是不是乙個合理的設計呢?如果這是乙個合理的設計,又不想作出這樣的讓步……我們又該怎麼做呢?
關於這點,我有自己的想法,不過還是想先聽一下您的意見。
物件導向與protected
拍腦殼所想之 戲言物件導向 說到protected這個詞,我不可避免的就會想到乙個概念 物件導向。那麼什麼是物件導向呢?其實我個人認為物件導向這個概念是一直在發展變化的,到了今天,物件導向這個詞也許讓它叫做面向抽象更加貼切。在剛剛建立物件導向這個概念的時候,大概連創造者對於到底什麼是物件導向都不是很...
JAVA中protected的作用
1 public public表明該資料成員 成員函式是對所有使用者開放的,所有使用者都可以直接進行呼叫 2 private private表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用,私有財產神聖不可侵犯嘛,即便是子女,朋友,都不可以使用。3 protected prot...
有關類的靜態成員初始化
有四個檔案 class.h,class.cpp,fun.h,fun.cpp 1.第一種情況 class.h include class c class.cpp include class.h int main class.h 5 error iso c forbids in class initia...