2013-09-25 85 views
0

剛剛遇到問題。 我正在嘗試做一個wcf服務unittest準備好或更好的所有代碼都必須使用unittest進行測試。WCF調用不接口的方法?

Atm它不可能coze我已經連接到每次使用的crm 2011服務器。
所以我用一個接口代替它。但我想單元測試WCF,就像你使用它。
現在我的想法是做一個公開的方法,並給出一個假連接。

現在我的問題是有可能調用此方法(例如:ConnectionHandler),即使它不在接口中?

這應該是這樣的:

public interface IWCF 
{ 
    [OperationContract] 
    bool method1(); 

    [OperationContract] 
    bool method2(); 
} 

public class WCF: IWCF 
{ 

    public bool method1(){ 
    ... 
    } 

    public bool method2(){ 
    ... 
    } 

    private connection connectionHandler; 
    public connection ConnectionHandler(Iconnection con){ 
     if(con != null){ 
      connectionHandler = con; 
     } else { 
      connectionHandler = takedefault; 
     } 
    } 
} 

編輯
啊我忘了告訴這一點:我其實心裏有安全,我不想讓任何人都可以傳遞到不同的連接該服務器僅用於單元測試目的。

+0

你試圖嘲笑你的聯繫?你應該看看不同的模擬框架,因爲這正是你想要完成的。 – CharlesAD

+0

是啊那就是即時通訊試圖做的事情:-D但是如果我不能注入嘲笑的連接我不能單元測試它。但與答案形式user2382536我明白如何做到這一點。我擔心的是,不要讓客戶端有權更改連接。 – domiSchenk

回答

0

任何精心設計的代碼片的重要特徵之一是,你明確了你公開給你的客戶端的功能。這成爲面向服務的應用程序的一個關鍵特性,因爲您正在以標準化方式公開外部客戶端使用的功能。

調用不屬於接口一部分的方法原則上不好,因爲您現在正在編程到實現而不是接口。令人高興的是WCF知道這一點,不會讓你的方法不在界面上,因爲它沒有用OperationContract屬性裝飾。

關於你的代碼 - 我不確定你到底想要達到什麼目的 - 有一個客戶端設置(我認爲是)像數據庫連接這樣的東西讓我有點不安(爲了開始這個意味着你的服務處於某種違背Service statelessness principle的狀態)。這並不意味着你所做的一定是錯誤的,但你應該發現你很少在設計良好的應用程序中違反這個規定。

這就是說,如果要公開的功能不同區域不同客戶正確的方式做,這是你的服務暴露端點分別代表不同的合同:

[ServiceContract] 
public interface IWCF 
{ 
    [OperationContract] 
    bool method1(); 

    [OperationContract] 
    bool method2(); 
} 

[ServiceContract] 
public interface IConnectionWCF 
{ 
    [OperationContract] 
    bool SetConnection(string connection); 
} 

public class WCF : IWCF, IConnectionWCF 
{ 
    public bool method1() 
    { 
     ... 
    } 

    public bool method2() 
    { 
     ... 
    } 

    public bool SetConnection(string connection) 
    { 
     ... 
    } 
} 

您還需要銘記WCF服務接收到的所有內容都必須先由客戶端序列化,然後通過網絡發送,然後在服務器上反序列化。你非常在這裏處理具體的課程 - 而不是抽象。將接口(如Iconnection)作爲參數傳遞給服務調用在面向服務的環境中確實沒有任何意義。

關於單元測試 - 請記住,基本上類WCF只是一個普通的舊類。你可以單獨測試這個類,並將它作爲一個WCF服務。您不應該在單元測試中設置任何服務託管功能 - 您要檢查您編寫的代碼是否正確 - WCF堆棧已經過Microsoft測試。

編輯

在回答您的意見,建議作爲here,你應該使用的構造方法注入設置連接對象時的類實例化。這就提出瞭如何獲得對WCF服務實例化的控制權的問題。你需要實現IInstanceProvider,或者更詳細的實現請參見here。這樣,當你的服務在WCF中託管時,你使用IInstanceProvider,當你測試時你只需將你的假連接對象傳遞給構造函數。

編輯

爲了澄清,該等級的單元測試將類似於此:

[TestClass] 
public class UnitTests 
{ 
    [TestMethod] 
    public void Test() 
    { 
     Iconnection connection = new FakeConnection(); 
     WCF classUnderTest = new WCF(connection); 

     //Run test logic 
    } 
} 
+0

首先我嘗試單元測試我的WCF方法(method1/method2)。 而且他們直接連接到crm 2011/DB服務器。 現在我想刪除這個直接連接,所以我可以注入一個假連接,所以我可以測試這些methodes。 但我不知道給wcf調用者改變連接的能力:-D – domiSchenk

+0

如果有人打電話給我的wcf,它仍然有可能給它一個不同的連接嗎?我只想單元測試能夠給我的wcf自定義連接 – domiSchenk

+0

剛剛在svc/wsdl文件中看到,您將無法爲構造函數提供參數?!這是正確的嗎? – domiSchenk

1

可以調用此方法,您可以將接口強制轉換爲具體對象。但那會損害調用代碼,它不應該知道你的服務的實現細節。

我會在你的sittuation reccomend使用constrcutor注入以便爲您服務implemetation應該是這樣的:

public interface IWCF 
{ 
    [OperationContract] 
    bool method1(); 

    [OperationContract] 
    bool method2(); 
} 

public class WCF: IWCF 
{ 
    private connection connectionHandler; 

    public WCF(Iconnection con) 
    { 
     if(con != null){ 
      connectionHandler = con; 
     } else { 
      connectionHandler = takedefault; 
     } 
    } 

    public bool method1(){ 
    ... 
    } 

    public bool method2(){ 
    ... 
    } 



} 

在這種情況下,客戶端代碼不會知道服務實現的細節,如果你使用在客戶端的constrcutor注入以及

+0

啊我忘了告訴這個:我實際上有安全的想法,我不希望任何人都可以通過一個不同的連接到服務器,它僅用於單元測試目的。 – domiSchenk