2011-03-31 51 views
1

這是我的問題:如何在這種情況下使用模擬?

我有一個n層應用程序,我必須編寫單元測試。單元測試是針對業務層的。

我有一個測試方法叫做Insert(),這個方法使用了兩個繼承的受保護方法,並直接從數據訪問層調用一個方法。

所以我做了一個模擬對象的DAL。但這裏有一點,在(編輯:)保護方法從繼承,它將使用DAL中的另一個對象!看來這是不可能的嘲笑這一個!

下面是測試代碼的方法:

public int Insert(MYOBJECT aMyObject) 
    { 
      //first inherited method use the FIRSTDALOBJECT so the mock object --> No problem 
      aMyObject.SomeField= FirstInherited(); 

      //Second inherited method (see after) --> my problem 
      aMyObject.SomeOtherField = SecondInherited(); 

      // Direct access to DALMethod, use FIRSTDALOBJECT so the mock -->No Problem 
      return this.FIRSTDALOBJECT.Insert(aMyObject);    
    } 

這裏是SecondInherited方法:

protected string SecondInherited() 
    { 
     // Here is my problem, the mock here seems not be possible for seconddalobject           
     return (new SECONDDALOBJECT Sdo().Stuff()); 
    } 

這裏是單元測試方法代碼:

[TestMethod()] 
    public void InsertTest() 
    { 
     BLLCLASS_Accessor target = new BLLCLASS_Accessor(); 
     MYOBJECT aMyObject = new MYOBJECT { SomeField = null, SomeOtherField = 1 }; 
     int expected = 1; 
     int actual; 

     //mock 
     var Mock = new Mock<DAL.INTERFACES.IFIRSTDALOBJECT>(); 
     //Rec for calls 
     List<SOMECLASS> retour = new List<SOMECLASS>(); 
     retour.Add(new SOMECLASS()); 

     //Here is the second call (last from method to test) 
     Mock 
      .Setup(p => p.Insert(aMyObject)) 
      .Returns(1); 

     // Here is the first call (from the FirstInherited()) 
     Mock 
      .Setup(p => p.GetLast()) 
      .Returns(50); 
     // Replace the real by the mock 
     target.demande_provider = Mock.Object; 

     actual = target.Insert(aMyObject); 
     Assert.AreEqual(/*Some assertion stuff*/); 
    } 

謝謝閱讀所有的問題:-)希望它是清楚的。

回答

3

您的文字似乎是說, SecondInheritedprivate,而在代碼示例是 protected。無論如何,如果它不是 protected,我會建議更改其訪問限定符作爲第一步。

可以單獨創建一個子類用於測試目的,並覆蓋SecondInherited,以避免造成SECONDDALOBJECT,就回到適合你的測試一定的價值。

這樣你可以編寫你的第一個單元測試(s)與最小的變化被測試的類,從而最大限度地減少破壞的機率。一旦你進行了單元測試,這些允許你安全地進行更多的重構,最終實現更好的(更可測試/可嘲弄的)設計,例如使用Dependency Injection或工廠。 (我可能更喜歡這裏的Abstract Factory而不是Factory Method,因爲後者實際上會迫使你保留測試類的子類)。

基本的,強烈推薦的學習這種技術的書(還有更多)是Working Effectively With Legacy Code

+0

它受到保護,對我的錯誤感到抱歉。 – bAN 2011-03-31 09:09:12

+0

+1:快速結果的良好解決方案 – 2011-03-31 09:09:35

+0

@bAN,感謝您的澄清,這種解決方案更容易。 – 2011-03-31 09:13:37

2

沒有機會用MOQ來嘲笑這一點。 你有兩個選擇:

  1. 使用TypeMock或痣嘲笑SECONDDALOBJECT
  2. 重構代碼,所以沒有在它的方式產生的SECONDDALOBJECT實例,但在某種程度上,可以是嘲笑(工廠方法,DI,...)(者優先!)