2011-07-04 20 views
1

我正在使用NUnit和Moq來測試一個使用通用WCF服務客戶端包裝的類I wrote,並且我遇到了一個我找不到的錯誤。我有以下接口:Moq和NUnit的運行時通用約束錯誤

public interface IService 
{ 
    void Call(); 
} 

...通過以下服務客戶端實現的:

public class ServiceClient : ClientBase<IService>, IService 
{ 
    public void Call() 
    { 
    } 
} 

與下面的一般限制......並通過此類包裝:

public class ServiceClientWrapper<TClient, TService> 
    where TClient : ClientBase<TService>, TService 
    where TService : class 
{ 
    public virtual TService CreateServiceClient() 
    { 
     return (TService)Activator.CreateInstance<TClient>(); 
    } 
} 

爲了使其可測試,我有一個包裝工廠,我可以嘲笑。該包裝工廠接口是這樣的:

public interface IServiceClientWrapperFactory 
{ 
    ServiceClientWrapper<TClient, TService> 
     CreateServiceClientWrapper<TClient, TService>() 
     where TClient : ClientBase<TService>, TService 
     where TService : class; 
} 

我測試此設置使用此代碼:

// A mock IService to return from my mock service wrapper: 
var mockService = new Mock<IService>(); 

// A mock client wrapper to return from my mock wrapper factory: 
var mockClientWrapper = 
    new Mock<ServiceClientWrapper<ServiceClient, IService>>(); 
mockClientWrapper 
    .Setup(mcw => mcw.CreateServiceClient()) 
    .Returns(mockService.Object); 

// A mock wrapper factory to inject into a client object: 
var mockClientWrapperFactory = new Mock<IServiceClientWrapperFactory>(); 
mockClientWrapperFactory 
    .Setup(mcwf => mcwf.CreateServiceClientWrapper<ServiceClient, IService>()) 
    .Returns(mockClientWrapper.Object); 

// Get the mock client wrapper from the mock wrapper factory - boom! 
mockClientWrapperFactory.Object 
    .CreateServiceClientWrapper<ServiceClient, IService>(); 

錯誤是:

GenericArguments [0], 'TService',上 'ServiceClientWrapper`2 [TClient,TService]' 違反了參數'TClient'類型 的限制。

約束是哪裏,我說他們是相同的,它編譯和運行得很好,如果我實現IServiceClientWrapperFactory和無起訂量運行它沒有引發錯誤...任何想法?

+1

而不是'return(TService)Activator.CreateInstance ();',你不能只添加'new()'約束,並直接新增它嗎?此外,看起來你正在做一個比它需要更難的簡單問題。我沒有看到你的代碼的其餘部分,但它似乎可以簡單地將'IService'注入到使用它們的類中,並丟棄所有這些代碼。 –

+0

我可以,如果我真的使用的類有一個無參數的構造函數,但[它不](http://geekswithblogs.net/mrsteve/archive/2011/06/30/generic-disposable-wcf-service- client.aspx)。出於問題的目的,您可以忽略該行。好點重新:直接注入一個IService,但在真正的應用程序中,類正在創建WCF服務客戶端,這意味着類的客戶端將不得不創建WCF服務客戶端...客戶端可以使用工廠,但它有點兒附帶解決問題。 –

回答

2

我玩了一下代碼,得到了同樣的結果。據我所知,你的定義沒有任何問題。

看起來它可能是Moq中的一個錯誤,在實現具有各種通用約束組合的模擬時,

我嘗試刪除各種約束(並根據需要註釋掉或修改代碼)。看來如果我從where TClient : ... , TService刪除TService,那麼我不會得到這個錯誤。

這似乎是由事實進一步證實已經出現了在過去的多個類似的錯誤:

僅供參考,我習慣瑞普你的問題是版本:Moq.4.0.10827,NET40(不是NET40-RequiresCastle)

+0

是的,我發現如果我改變'在哪裏TClient:ClientBase ,TService'到'其中TClient:ClientBase '它工作正常 - 只是想確保我沒有漏掉任何明顯的東西。感謝您檢查:) –