2017-06-12 108 views
0

這是我班的簡化模型。靜態方法的調用是單元測試的測試用例嗎?

public static FooFactory 
{ 
    public void CreateFooByUrl(string url) 
    { 
     try 
     { 
      // business logic 
     } 
     catch(Exception exc) 
     { 
      ApplicationLogger.LogError(exc); 
     } 
    } 
} 

ApplicationLogger是整個解決方案中使用的靜態類。我如何驗證錯誤是否被記錄?

這是我的測試方法的例子。

[TestMethod] 
public void CreateFooExpectedError() 
{ 
    // Arrange 
    string testUrl = "fakeUrl"; 

    // Act 
    FooFactory.CreateFoo(testUrl); 

    // Assert 
    /ApplicationLogger.LogError(); 
} 

如何檢查LogError方法是否被調用?它是一個測試用例嗎?

+1

@mason但是有try try catch塊嗎?一般來說,我並不滿意所有方法 – Icepickle

+0

這完全是一個完全不同的問題,如果不瞭解更多關於應用程序的知識,我無法回答。 – mason

+0

ApplicationLogger是如何正常配置的?你能動態地添加日誌目的地嗎? – Lee

回答

4

您對ApplicationLogger有很大的依賴性。這不好。現在你不能測試那個CreateFooByUrl的作品而沒有實際記錄一些東西。相反,讓它使用IApplicationLogger(一個接口),然後你可以提供該接口的模擬實現作爲單元測試的一部分。這可能意味着您需要將FooFactory設爲非靜態(您不能在靜態類中使用非靜態方法,就像您所示),或者將CreateFooByUrl更改爲接受IApplicationLogger作爲參數(messier)。

這裏的清潔方式:

public interface IApplicationLogger 
{ 
    void LogError(Exception exception); 
} 

public class ApplicationLogger : IApplicationLogger 
{ 
    public void LogError(Exception exception) 
    { 
     //do stuff 
    } 
} 

public class FooFactory 
{ 
    private readonly IApplicationLogger _logger; 

    public FooFactory(IApplicationLogger logger) 
    { 
     _logger = logger; 
    } 

    public void CreateFooByUrl(string url) 
    { 
     try 
     { 
      // business logic 
     } 
     catch(Exception exception) 
     { 
      _logger.LogError(exception); 
     } 
    } 
} 

//now for the unit test 
public void TestCreate() 
{ 
    //arrange 
    var mockLogger = new Mock<IApplicationLogger>(MockBehavior.Strict); 
    mockLogger.Setup(m => m.LogError(It.IsAny<Exception>())); 

    var factory = new FooFactory(mockLogger.Object); 

    //act 
    factory.CreateFooByUrl("something that will cause exception"); 


    //assert 
    mockLogger.Verify(m => m.LogError(It.IsAny<Exception>())); 
} 

這是從關注角度來看,分離好得多。爲什麼要FooFactory關心事情如何記錄?它只需要能夠記錄事物。這就是爲什麼最好對接口進行編碼。那麼如果你想切換日誌實現,你只需創建一個實現IApplicationLogger的新類,一切都將神奇地工作。