最小起订量设置在告知时没有 return 值
Moq setup does not return value while told
我的测试场景中有这个:
var dbConnection = new Mock<IDbConnection>();
dbConnection.Setup(x => x.SearchFor<User>("users", y => y.Password =="12345"
&& y.Username == "tester")).Returns(new List<User>{
new User{
Username = "tester",
Password = "12345"
}}.AsQueryable());
var users = new Users.Users(dbConnection.Object);
var user = users.Get("tester", "12345");
查看 Get 方法时:
public User Get(string username, string password){
var total = _dbConnection.SearchFor<User>("users", y =>
y.Password == password &&
y.Username == username).Single();
return total;
}
根据我在 Internet 上找到的大多数示例,它应该可以工作,但它总是给我:
System.InvalidOperationException: Sequence contains no elements
当我将 Get 方法更改为:
public User Get(string username, string password){
var total = _dbConnection.SearchFor<User>("users", y =>
y.Password == "12345" &&
y.Username == "tester").Single();
return total;
}
它神奇地工作,但 get 方法在业务层中,就像我们都知道的那样...设置硬编码的用户名和密码从来都不好。
问题是:如何让最小起订量的设置正常工作?我做错了什么?
所以你正在设置,期待参数 "users"
和 y => y.Password == "12345" && y.UserName == "tester"
。但是,您的第二个参数是 lambda,很难比较(如果不是不可能的话?)。因此,当 Moq 检查您是否已调用它时,它最终会尝试比较 lambda,这可能会失败。
例如下面的代码显示了两个看似相同的函数,但它们并不被认为是相等的:
Func<bool> a = () => true;
Func<bool> b = () => true;
(a == b).Dump(); //False
a.Equals(b).Dump(); //False
因此 Moq 不知道使用您设置的 return 值。
您可能需要实现一个模拟存储库,它实际上将 运行 lambda,而不是试图找到您提供的相同的存储库。
像这样:
class TestRepo
{
public void Add<T>(T myType)
{
//add to an in-memory "database"
}
public IEnumerable<T> Get<T>(Expression<Func<T, bool>> filter)
{
return inMemoryDataBase.Where(filter);
}
}
这将使您的 Get
方法看起来像这样:
public User Get(string username, string password){
var total = RealRepo.Get<User>(y =>
y.Password == "12345" &&
y.Username == "tester").Single();
return total;
}
你的测试:
var repo = new TestRepo();
repo.Add(new User { Username = "tester", Password = "12345" });
var users = new Users.Users(dbConnection.Object);
var user = users.Get("tester", "12345");
这是一个有点相关的问题,其中用户试图找到一种方法来唯一标识 lambda,以便它们可以 "compared" 以您希望的方式出现。我不知道在那里找到了任何完美的解决方案。
我的测试场景中有这个:
var dbConnection = new Mock<IDbConnection>();
dbConnection.Setup(x => x.SearchFor<User>("users", y => y.Password =="12345"
&& y.Username == "tester")).Returns(new List<User>{
new User{
Username = "tester",
Password = "12345"
}}.AsQueryable());
var users = new Users.Users(dbConnection.Object);
var user = users.Get("tester", "12345");
查看 Get 方法时:
public User Get(string username, string password){
var total = _dbConnection.SearchFor<User>("users", y =>
y.Password == password &&
y.Username == username).Single();
return total;
}
根据我在 Internet 上找到的大多数示例,它应该可以工作,但它总是给我:
System.InvalidOperationException: Sequence contains no elements
当我将 Get 方法更改为:
public User Get(string username, string password){
var total = _dbConnection.SearchFor<User>("users", y =>
y.Password == "12345" &&
y.Username == "tester").Single();
return total;
}
它神奇地工作,但 get 方法在业务层中,就像我们都知道的那样...设置硬编码的用户名和密码从来都不好。
问题是:如何让最小起订量的设置正常工作?我做错了什么?
所以你正在设置,期待参数 "users"
和 y => y.Password == "12345" && y.UserName == "tester"
。但是,您的第二个参数是 lambda,很难比较(如果不是不可能的话?)。因此,当 Moq 检查您是否已调用它时,它最终会尝试比较 lambda,这可能会失败。
例如下面的代码显示了两个看似相同的函数,但它们并不被认为是相等的:
Func<bool> a = () => true;
Func<bool> b = () => true;
(a == b).Dump(); //False
a.Equals(b).Dump(); //False
因此 Moq 不知道使用您设置的 return 值。
您可能需要实现一个模拟存储库,它实际上将 运行 lambda,而不是试图找到您提供的相同的存储库。
像这样:
class TestRepo
{
public void Add<T>(T myType)
{
//add to an in-memory "database"
}
public IEnumerable<T> Get<T>(Expression<Func<T, bool>> filter)
{
return inMemoryDataBase.Where(filter);
}
}
这将使您的 Get
方法看起来像这样:
public User Get(string username, string password){
var total = RealRepo.Get<User>(y =>
y.Password == "12345" &&
y.Username == "tester").Single();
return total;
}
你的测试:
var repo = new TestRepo();
repo.Add(new User { Username = "tester", Password = "12345" });
var users = new Users.Users(dbConnection.Object);
var user = users.Get("tester", "12345");
这是一个有点相关的问题,其中用户试图找到一种方法来唯一标识 lambda,以便它们可以 "compared" 以您希望的方式出现。我不知道在那里找到了任何完美的解决方案。