【问题标题】:Mocking a generic repository method模拟通用存储库方法
【发布时间】:2013-02-18 17:54:06
【问题描述】:

为了对我的 asp.net MVC Web 应用程序进行单元测试,我想模拟我的 IGenericRepository(我正在使用 Moq)。

必须模拟的方法如下所示:

IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, 
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "");

我已经毫无问题地模拟了存储库:

useraccountRepository = new Mock<IGenericRepository<Useraccount>>();

现在我想告诉 Moq,当我的接口的 Get 方法被调用时,应该返回一个用户帐户列表:

useraccountRepository.Setup(r => r.Get(u => u.Email == useraccount.Email && u.Password == useraccount.Password)).Returns(useraccounts);

我认为我的第二个 lambda 中有一个错误,因为这个有效:

useraccountRepository.Setup(r => r.Get(null, null, "")).Returns(useraccounts);

但我的错误在哪里?

什么也有效:

useraccountRepository.Setup(r => r.Get(u => u.Email == useraccount.Email 
            && u.Password == useraccount.Password, null, "")).Returns(useraccounts);

看起来默认参数值不适用于我的模拟。这是为什么呢?

如果我使用

useraccountRepository.Setup(r => r.Get(u => u.Email == useraccount.Email 
            && u.Password == useraccount.Password, null, "")).Returns(useraccounts);

无论如何,那么当调用Get消息时,我的控制器中的方法会抛出异常:

private bool validateUser(Useraccount useraccount)
    {
        try
        {
            Useraccount useraccountLogin = UnitOfWork.UseraccountRepository.Get(
                u => u.Email == useraccount.Email && u.Password == useraccount.Password).Single<Useraccount>();

            return (useraccountLogin != null);
        }
        catch (Exception exc)
        {
            return false;
        }            
    }

我的错误在哪里?

提前谢谢你。 迈克尔

【问题讨论】:

  • 什么不起作用并且抛出哪个异常?您可以像专业人士一样浏览细节......
  • 很抱歉让您感到困惑。如果在我的单元测试中调用了 validateUser(...) 方法(从控制器方法内部),它会抛出一个异常,其中调用了 UseraccountRepository.Get(...):[System.InvalidOperationException] = {"Sequence contains no元素”}。 " 在 System.Linq.Enumerable.Single[TSource](IEnumerable`1 源)\r\n 在 ..."。

标签: asp.net-mvc-3 linq lambda mocking moq


【解决方案1】:

根据这个问题Moq.Mock<T> - how to setup a method that takes an expression,Moq 不支持对表达式参数设置约束。

【讨论】:

  • 我发现并且至少有效的是:useraccountRepository.Setup(r => r.Get(It.IsAny>>(), null, " ")).Returns(用户帐户);有没有更好的方法,或者这已经是模拟我展示的存储库方法的最佳方法了吗?
  • 我认为这是您最好的选择。但显然,当您需要使用不同的表达式模拟两个不同的调用时,您会遇到问题。不过,我会考虑取消通用回购。许多专家认为它是一种反模式,部分原因是可测试性差。
  • 感谢您的帮助。你的链接把我带到了正确的轨道。 :)
猜你喜欢
  • 2017-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多