款待SecondClass
作爲第三方的依賴,將其封裝在你背後控制代碼創建的,你從依賴想要的功能抽象;
public interface ISecondClass {
List<string> GenerateFile();
}
A類也有太多的顧慮,應該刪除任何不屬於A級的責任/問題。
public interface IDataClassParser {
DataClass Parse(string data);
}
public class DefaultDataClassParser : IDataClassParser {
public DataClass Parse(string data) {
return new DataClass {
Property1 = data.Substring(0, 2),
Property2 = data.Substring(3, 5),
Property3 = data.Substring(9, 10)
};
}
}
以上是用於演示目的的簡單示例。
重構目標類到現在明確依賴於抽象而不是結核。
public class A {
private readonly ISecondClass B;
private readonly IDataClassParser parser;
public A(ISecondClass B, IDataClassParser parser) {
this.B = B;
this.parser = parser;
}
public List<DataClass> MethodUnderTest() {
List<string> requiredData = B.GenerateFile();
return requiredData.Select(createNewDataClass).ToList();
}
private DataClass createNewDataClass(string r) {
return parser.Parse(r);
}
}
類A
不再緊密耦合到實施關注和現在被測方法可以單獨測試。
實施例測試
[TestClass]
public class ATest {
[TestMethod]
public void MethodUnderTest_Should_Return_DataClassList() {
//Arrange
List<string> mockData = new List<string>();
//TODO: Populate mockData
var mockB = new Mock<ISecondClass>();
mockB.Setup(_ => _.GenerateFile()).Returns(mockData);
var sut = new A(mockB.Object, new DefaultDataClassParser());
//Act
var actual = sut.MethodUnderTest();
//Assert
//TODO: assert that the actual result satisfies expectations
}
}
技術上上述現在只實際測試分析器,因此額外的測試可被寫入,以測試在隔離解析代碼。
[TestClass]
public class DataClassParserTest {
[TestMethod]
public void DataClassParser_Should_Return_DataClass() {
//Arrange
string mockData = "..."; //TODO: Populate mockData
var sut = new DefaultDataClassParser();
//Act
var actual = sut.Parse(mockData);
//Assert
//TODO: assert that the actual result satisfies expectations
}
}
最後,在生產,你的長期運行的類的實現將從抽象推導和封裝相關SecondClass
public class SecondClassWrapper : ISecondClass {
private SecondClass B = new SecondClass();
public List<string> GenerateFile() {
return B.GenerateFile();
}
}
發生在這裏的太多顧慮。你最終想要測試什麼?如果涉及的類是我們設計的,那麼您應該用單元測試替代依賴關係。根據描述這種緊密耦合的氣味。 – Nkosi
我不是SecondClass的原始開發人員,也不是我編碼的方式,但它是我所堅持的。我最終想測試B.GenerateFile返回列表,然後我可以解析成列表 –
gheff
如果您實際上並未嘗試單元測試SecodClass,那麼將SecondClass作爲第三方並將其抽象爲您控制的代碼的後面。這樣你就可以隔離你的代碼並正確地維護/測試它。 – Nkosi