好的,我正在努力弄清楚如何为一个接受表达式的方法设置moq。有很多关于如何使用它的例子.IsAny<> ...这不是我所追求的。我正在做一个约束,所以It.Is<>。我已经设置了但它永远不会返回我要求它返回的值。
// Expression being setup
Expression<Func<UserBinding, bool>> testExpression = binding =>
binding.User.Username == "Testing Framework";
// Setup of what expression to look for.
this.bindingManager.Setup(
c => c.GetUserBinding(It.Is<Expression<Func<UserBinding, bool>>>
(criteria => criteria == testExpression)))
.Returns(new List<UserBinding>() { testBinding }.AsQueryable());
// Line of code call from within the class being tested. So this is being mocked and should return the defined object when the same lambda is passed in.
this.bindingManager.GetUserBinding(b => b.User.Username == username)
.SingleOrDefault();
// class under test. So for the test this is being called.
// so this is the method being called and inside this method is where the binding manager is being mocked and called.
var response = this.controller.SendMessage(message, true).Result;
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
// inside the controller.SendMessage method this method is called with the lambda expression. I have verified the usernames match but when the setup is It.Is this returns null instead of the object setup in the "setup" call.
this.bindingManager.GetUserBinding(b => b.User.Username == username)
.SingleOrDefault();
如果我将设置更改为It.IsAny ...它工作并返回“returns”方法中的预期对象设置。
我已经找到了一些如何在网络上执行此操作的示例,其中一个是这样做,另一个是使用编译,但我无法让它工作。你如何让这个特定表达式工作?
所以在我的情况下,如果有人给我一个这样的表达式:
binding => binding.User.Username == "Testing Framework";
我需要像这样的UserBinding:
var testBinding = new UserBinding { Binding = new Binding { Name = "Default binding" }, Domain = "test.com", User = new User() { Username = "Testing Framework" } };
然后我可以像这样创建我的“设置”调用:
this.bindingManager.Setup(c => c.GetUserBinding(It.Is<Expression<Func<UserBinding, bool>>>(y => y.Compile()(testBinding))))
.Returns(new List<UserBinding>() { testBinding }.AsQueryable());
这有效,在我的情况下,我已经设置了返回测试绑定对象。如果您将testBinding更改为(请注意我更改了用户名):
var testBinding = new UserBinding { Binding = new Binding { Name = "Default binding" }, Domain = "test.com", User = new User() { Username = "Testing Framework2" } };
它不起作用,因为我测试的系统中的代码生成一个表达式,寻找“Test Framework”
也许只是我没有连接这个点,但希望它能帮助别人。
答案 0 :(得分:5)
这里的真正问题似乎是如何比较两个lambda表达式,就像你在It.Is<Expression<Func<UserBinding, bool>>>
(criteria => criteria == testExpression)
子句中尝试的那样。使用@ neleus对this question的回答,我可以提出实际通过的测试:
readonly Mock<IBindingManager> bindingManager = new Mock<IBindingManager>();
[Test]
public void TestMethod()
{
Expression<Func<string, bool>> testExpression = binding => (binding == "Testing Framework");
bindingManager.Setup(c => c.GetUserBinding(It.Is<Expression<Func<string, bool>>>(
criteria => LambdaCompare.Eq(criteria, testExpression)))).Returns(new List<string>());
var oc = new OtherClass(bindingManager.Object);
var actual = oc.Test(b => b == "Testing Framework");
Assert.That(actual, Is.Not.Null);
bindingManager.Verify(c => c.GetUserBinding(It.Is<Expression<Func<string, bool>>>(
criteria => LambdaCompare.Eq(criteria, testExpression))), Times.Once());
}
请注意使用LambdaCompare.Eq
静态方法来比较表达式是否相同。如果我将表达式与==
甚至Equals
进行比较,则测试失败。
答案 1 :(得分:0)
当我寻找模拟Where()并过滤一些数据的方法时, 在被测试的代码中看起来像:
private static string GetStringFromUser(string prompt)
{
Console.Write(prompt);
return Console.ReadLine();
}
private static double GetDoubleFromUser(string prompt)
{
double input;
// double.TryParse attempts to convert a string into a double, and
// it returns a bool that indicates success. If it's successful,
// then the out parameter will contain the converted value. Here
// we loop until we get a successful result, then we return the value.
do
{
Console.Write(prompt);
} while (!double.TryParse(Console.ReadLine(), out input));
return input;
}
public static double GetBMI(double height, double weight)
{
return weight / Math.Pow(height, 2) * 703;
}
private static ConsoleKeyInfo GetKeyFromUser(string prompt)
{
Console.Write(prompt);
var key = Console.ReadKey();
Console.WriteLine();
return key;
}
private static void Main()
{
string name = GetStringFromUser("Enter your name: ");
double weight = GetDoubleFromUser("Enter your weight in pounds: ");
double height = GetDoubleFromUser("Enter your height in inches: ");
double bmi = GetBMI(height, weight);
Console.WriteLine($"Thank you, {name}. Your BMI is: {bmi}");
GetKeyFromUser("\n\nDone! Press any key to exit...");
}
我可以根据其他人的答案设计这样的示例:
Repository<Customer>().Where(x=>x.IsActive).ToList()
也许对羽毛开发者会有帮助。