2017-10-15 42 views
3

我正在努力通過編寫一些可以爲我創建屬性的助手來使EF更容易進行單元測試。我有一對夫婦的支持領域打開帶有通用返回類型的類型

private Mock<DbSet<Workflow>> mockedWorkFlows; 
private Mock<DbSet<WorkflowError>> mockedWorkFlowErrors; 

而且我希望有一個通用的功能,能夠回到我正確的支持字段具有以下功能

public Mock<DbSet<T>> Mocked<T>(T t) where T : class 
{ 
    if ((object)t is Workflow) 
    { 
     return mockedWorkFlows; //cannot Workflow to T 
    } 
} 

有,我想一些私人支持字段根據傳遞的類型返回。

但是,即使我添加了類別約束Workflow,我也會得到相同的錯誤。

我也嘗試切換t's類型,但沒有運氣。幾個後備字段的類型不共享除對象以外的共同祖先。我正在嘗試做什麼?

+0

我沒有看到這個方法的重點。創建一個模擬需要1行代碼,如果你想設置模擬,你必須單獨設置每一個模擬,所以你爲什麼不創建一個工廠模擬某些類型。 – FCin

+0

從你的EF上下文中嘲笑一個IDbSet 不止一行代碼。我有一個流暢的接口來分配數據,但是你必須在某個地方公開後臺字段,因爲當你窺探那些實際上被調用的時候。我只想要一個較小的API,而不是爲上下文的所有IDbSet屬性設置WorkflowsMo​​cked,WorkflowErrorsMocked等。 – wootscootinboogie

+0

而不是模擬'DbSet',你有沒有考慮嘲笑'SqlConnection',例如,使用Effort框架? https://github.com/tamasflamich/effort –

回答

6

如果我正確理解你的意圖 - 你可以做這樣的:

// no need to pass instance of T - why? 
public Mock<DbSet<T>> Mocked<T>() where T : class 
{ 
    if (typeof(T) == typeof(Workflow)) { 
     // first cast to object, then to return type to avoid compile error 
     // compiler does not know mockedWorkFlows is Mock<DbSet<T>>, but you 
     // know it already, because you checked type 'T' 
     return (Mock<DbSet<T>>) (object) mockedWorkFlows; //cannot Workflow to T 
    } 
    // etc 
    return null; 
} 

無論是好主意與否是一個不同的故事。

+0

這就是我正在尋找的。我正在嘗試使用C#7類型的開關,但最終我正在尋找(儘管現在我得到了一個不同的錯誤!:)) – wootscootinboogie

1

有可能與when警衛嚴重濫用C#7的switch達到你想要的東西通過一個無關值切換並使用var模式:

public Mock<DbSet<T>> Mocked<T>() where T : class 
{ 
    switch(true) 
    { 
     case var _ when typeof(T) == typeof(Workflow): 
      return ... 
     case var _ when typeof(T) == typeof(WorkflowError): 
      return ... 
     default: 
      return null; 
    } 
} 

但它的真正可怕的代碼,所以請不要不要這樣做!

能夠匹配switch語句中的類型是一個非常普遍的要求。有關於在github上正式語言回購的C#改進建議(請參閱Proposal: switch on System.Type和p Proposal: Pattern match via generic constraint)。當更多的模式匹配功能被添加到C#(currently, set for "a 7.X release")時,我們可能會獲得更好的語法來實現此功能。