你將不得不分開你的類中的第三方邏輯。
例子:
public class MyClass
{
private SshMagic _sshMagic = new SshMagic(); // or something like that
...
ResultObject getServerStatus(string ip,string user,string pass,...)
{
if (..)
{
return _sshMagic.Something();
}
else
{
...
}
}
}
要測試的是什麼是你的代碼:的條件,循環等。return _sshMagic.Something()
線是一個外部的邏輯,你definitly不想測試一下。
第一步
將SshMagic包裝在接口後面。這將有兩個好處:
1)你可以隨時改變實現(就像一個帶有不同API的新版本出來,所以你必須重寫你的包裝器:所有其他代碼可能不需要位變化)
2)它總是一個很好的機會創建一個適配器,並專注於你想要做的而不是實現細節,例如SshMagic類。例如:如果你從來沒有在一個方法使用兩個參數出四,您可以隱藏它們,或者你如果要調用3種方法一起,你可以在一個方法將它們包裝...
例如:
public interface ISshMagic
{
...
ResultObject Something();
...
}
public class MyClass
{
private ISshMagic _sshMagic;
public MyClass(ISshMagic sshMagic)
{
_sshMagic = sshMagic;
}
...
}
第二步現在
,我們已經分開的依賴,我們會嘲笑混蛋。你必須選擇一個模擬框架,如Moq,Simple.Mocking等。爲了舉例,我將在這裏使用Simple.Mocking。
例
您可以創建MockObject:
[TestFixture]
public class UnitTesty
{
...
[Test]
public void GetServerStatus_Will_Call_Something_Of_SshMagic()
{
...
_mockSshMagic = Mock.Interface<ISshMagic>();
MyClass myClass = new MyClass(_mockSshMagic);
...
// we are setting up that _mockSshMagic.Something() will be called
Expect.Once.MethodCall(() => _mockSshMagic.Something());
...
// do your test here...
myClass.("255.255.255.0", "Me", "MyPassword", ...);
...
// we are checking that our expectations were met:
AssertInvocationsWereMade.MatchingExpectationsFor(_mockSshMagic);
}
}
哇那是一個直截了當的答案...謝謝:) –
我最大的問題是我必須爲已經存在的代碼創建測試單元(我有200多個獨立的類都在做其他的東西),現在我感到不做「測試驅動的發展「,因爲改變所有的東西這種方式的胡言亂語是非常多的工作:D –
那麼,它的一個共同的問題。可能你不能也不會涵蓋你的代碼中的每個類,但即使在這種情況下,它也會增加價值。當您重構或添加新代碼時,請在TDD中執行此操作,而舊的冷基座將慢慢消失:)。 – atoth