2011-03-17 53 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