【发布时间】:2014-04-23 17:39:51
【问题描述】:
我花了几天时间寻找允许我模拟由Expression<Func<T, bool>> 参数化的方法的解决方案。我找到了this。但不幸的是,当我想用字符串参数测试服务方法时它不起作用,例如:public IEnumerable<Person> FindByName(string name),如下所示:
using System;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace UnitTestProject
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var mock = new Mock<IRepository<Person>();
mock.Setup(r => r.Find(AreEqual<Person>(p => p.FirstName.Equals("Justin")))).Returns(new[]
{
new Person {FirstName = "Justin", LastName = "Smith"},
new Person {FirstName = "Justin", LastName = "Quincy"}
});
var personService = new PersonService(mock.Object);
Person[] justins = personService.FindByName("Justin").ToArray();
Person[] etheredges = personService.FindByName("Etheredge").ToArray();
Debugger.Break();
}
static Expression<Func<T, bool>> AreEqual<T>(Expression<Func<T, bool>> expr)
{
return Match.Create<Expression<Func<T, bool>>>(t => t.ToString() == expr.ToString());
}
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public interface IRepository<T>
{
IEnumerable<T> Find(Expression<Func<Person, bool>> predicate);
}
public class PersonService
{
readonly IRepository<Person> _repository;
public PersonService(IRepository<Person> repository)
{
_repository = repository;
}
public IEnumerable<Person> FindByName(string name)
{
return _repository.Find(p => p.FirstName.Equals(name));
}
}
}
当调试器中断时,我预计数组 justins 将包含上面列出的两项,而数组 etheredges 将不包含任何项。实际上它们都是空数组。我怀疑这是因为在FindByName 方法中,字符串不是直接提供的,而是通过变量name 提供的。
你知道如何解决这个问题吗?
【问题讨论】:
-
不清楚你想模拟什么以及你想测试什么。您想模拟表达式以测试使用它的类吗?或者你想模拟这个类来测试表达式?
-
我想模拟存储库的方法,从 db 返回通过提供的表达式的项目,并且我想测试更高级别的服务方法,该方法找到所有提供的名称作为字符串的项目。
-
您需要发布您的存储库代码才能收到答案。
标签: c# unit-testing mocking expression moq