2008-12-11 55 views
4

我想知道單元測試和使用語句是否可以真正結合在一起,因爲沒有辦法模擬在使用語句中實例化的一次性對象。我將如何能夠有效地單元測試包含以下使用語句的方法?包含使用語句的單元測試方法

 
public void MyMethod() 
{ 
    using(MyDisposableClass disp = new MyDisposableClass()) 
    { 
     ... 
    } 
} 

當你在進行單元測試時,是否使用簡單禁止的語句?

任何意見讚賞。

+0

不錯的q。替代品,我能想到的是比原來更多的工作.. – Gishu 2008-12-11 10:48:48

回答

4

不,使用語句當然不禁止。但是MyDisposableClass實際上做了什麼?這讓我覺得這不是使用陳述成爲問題的真正問題 - 這是創建一個您想要模擬的新對象的方法問題 - 問題。

你真的需要模擬MyDisposableClass嗎?它可以傳入MyMethod而不是在它內部創建嗎?與往常一樣,訣竅是如何在進程中插入並注入自己的對象...

+0

MyDisposableClass真的是一個外部系統的適配器,我需要Connect(),Login()和LogOut()處置。如果我將它作爲參數發佈,我會在父方法中遇到問題嗎? – Fadeproof 2008-12-11 11:09:23

3

既然你要嘲笑資源類我假設你已經有

interface IResource : IDisposable 
{ 
     void DoSomething(); 
} 

class DisposableResource : IResource 
{ 
    public void Dispose()  { Console.WriteLine("That's it. I'm outta here!"); } 
    public void DoSomething() { Console.WriteLine("Hard work this"); } 
} 

爲了能夠注入obj,你需要一個縫..即GetResource()

class MyClass 
{ 
    protected virtual IResource GetResource() 
    { 
     return new DisposableResource(); 
    } 
    public void MyMethod1() 
    { 
     using (IResource r = GetResource()) 
     { 
      r.DoSomething(); 
     } 
    } 
} 

在您的測試代碼中,只需簡單地繼承並重寫GetResource()以返回一個模擬。

class MySubClassForTest : MyClass 
{ 
    protected override IResource GetResource() 
    { 
     return new MockResource(); 
    } 
} 
class MockResource : IResource // or use a mock framework to create one 
{ 
    public void DoSomething()  { Console.WriteLine("Me work?"); } 
    public void Dispose()   { Console.WriteLine("Disposed Mock!"); } 
} 

就是這樣。

MyClass obj = new MyClass();   // production code 
obj.MyMethod1(); 

obj = new MySubClassForTest();   // test code 
obj.MyMethod1(); 
1

TypeMock將允許你嘲笑這一點。它通過動態修改IL來工作,因此不會嘲笑你無法模擬的東西。

但即使使用TypeMock,您仍應該看看Jon Skeet和Pop Catalin在上面所說的內容。如果您嘗試減少依賴關係的數量,您的代碼將更容易維護。