2011-03-17 60 views
5

這是我在這樣的第一次嘗試,所以希望這是簡單的。犀牛模擬實體框架使用的UnitOfWork模式不工作

我創建了一個使用實體框架訪問數據庫的WCF服務。我已經實現了一個接口,因此我的服務可以使用EF,同時仍然可以測試。

這裏是我的服務:

public class ProjectService : IProjectService 
{ 
    private IUnitOfWork db = null; 

    public ProjectService(IUnitOfWork unitofwork) 
    { 
     db = unitofwork; 
    } 

    public int RegisterSite(int CPUID) 
    { 
     if (db.Servers.Count(x => x.CPUID == CPUID) > 0) 
     { 
      // do something 
     } 

     return 0; 
    } 
} 

這裏是我的UnitOfWork接口:

public interface IUnitOfWork 
{ 
    IObjectSet<tblClient> Clients { get; } 
    IObjectSet<tblServer> Servers { get; } 
    IObjectSet<tblSite> Sites { get; } 
    IObjectSet<tblServerLog> ServerLogs { get; } 
    void Commit(); 
} 

當我使用這項服務的SQLUnitOfWork(使用EF)或用InMemoryUnitOfWork無論是具體實現(只是在內存對象),那麼它工作正常。

經過測試罰款與我的記憶對象我試過這個測試。

[Test] 
public void RegisterAnExistingServer() 
    { 
     MockRepository mocks = new MockRepository(); 

     IUnitOfWork MockUnitOfWork = mocks.DynamicMock<IUnitOfWork>(); 

     ProjectService service = new ProjectService(MockUnitOfWork); 


     Expect.Call(MockUnitOfWork.Servers.Count(x => x.CPUID == 1234)).Return(0); 

     mocks.ReplayAll(); 

     int NewSiteID = service.RegisterSite(1234); 

     mocks.VerifyAll(); 
    } 

但是當我嘗試使用它在犀牛模擬與預期的Servers.Count我得到以下錯誤:

System.ArgumentNullException : Value cannot be null. 
Parameter name: arguments 
at System.Linq.Expressions.Expression.RequiresCanRead(Expression expression, String paramName) 
at System.Linq.Expressions.Expression.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arg, ParameterInfo pi) 
at System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ref ReadOnlyCollection`1 arguments) 
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments) 
at System.Linq.Queryable.Count(IQueryable`1 source, Expression`1 predicate) 

我在做什麼錯?

+2

也許錯誤是指'Servers'爲空。我想你也必須設定這一點。 – 2011-03-17 06:32:34

+0

所以我加了這一行 'MockUnitOfWork.Servers = mocks.StrictMock >();'仍然是同樣的錯誤。這是你的意思嗎? – 2011-03-17 06:40:32

+0

一個建議是,我不會使用Record and Playback語法,因爲它已被首選的Arrange-Act-Assert樣式所取代。使用RhinoMocks,由於API處於相同的命名空間中(我上次檢查過),很難區分它們。 – aqwert 2011-03-17 07:57:49

回答

4

MikeEast是正確的。 Rhino.Mocks不會執行遞歸嘲諷。您需要模擬了服務器屬性返回的東西(只需要創建一個空的IObjectSet <tblServer>,並設置了作爲返回值)。

此外,您不希望對lambdas設置期望值。一旦編譯完成,代碼中的lambda和單元測試中的lambda是兩種完全不同的方法(並且你的期望總是失敗)。有關更多詳細信息,請參閱http://groups.google.com/group/rhinomocks/msg/318a35ae7536d90a

-6

內部可能存在一些反映,因此您沒有直接打電話給您的工作單元。

我強烈建議切換到NHibernate的。另外,溝WCF。

+0

您能否詳細說明一下?此外WCF和EF是我們正在使用的框架不能只是切換。 – 2011-03-17 06:45:45

+3

僅僅因爲你不知道答案就意味着他正在使用的框架不好,他應該切換!你如何獲得像這樣的答案的聲譽呢? – 2012-08-12 20:05:30

+0

我有這個聲譽,因爲人們投票給我的答案。比較nhibernate(第一級和第二級緩存,擴展點,多個數據庫等)與EF,你會看到。然後看看像ServiceStack(在代碼設置,易於前瞻性維護),並將其與WCF進行比較。問題是「我做錯了什麼」。所以建議NH和SS是適用的。 – 2012-08-13 03:00:43