简体   繁体   English

起订量与 lambda 表达式?

[英]Moq with lambda expressions?

I am trying to test an application service using Moq 4.0.10827 (on NuGet) and need to query a repository:我正在尝试使用 Moq 4.0.10827(在 NuGet 上)测试应用程序服务,并且需要查询存储库:

public class MyService
{
    Repository<MyObject> _Repo;

    public MyObject Get (string SomeConstraint)
    {
        return _Repo
            .GetTheFirstOneOrReturnNull (M => M.Constraint.Equals (
                SomeContraint, StringComparison.InvariantCultureIgnoreCase
            ));  // GetTheFirstOneOrReturnNull takes a Func<MyObject, bool>
    }
}

How do I replicate the lambda expression with Moq?如何使用 Moq 复制 lambda 表达式? I keep getting the "Unsupported expression" exception.我不断收到“不支持的表达式”异常。

Here is an idea of what I'm doing already:这是我已经在做的事情的一个想法:

[TestMethod]
public void GetByMyConstraintShouldReturnWithMyObject ()
{
    // Arrange
    const string MyConstraint = "Constraint";
    MyObject Expected = new MyObject { Constraint = MyConstraint };
    Mock<Repository<MyObject>> MockRepo = new Mock<Repository<MyObject>> ();
    MockRepo.Setup (x => x.GetTheFirstOneOrReturnNull (M => M.Constraint.Equals (MyConstraint, StringComparison.InvariantCultureIgnoreCase)))
            .Returns (Expected).Verifable ();
    MyService Service = new MyService (MockRepo.Object);

    // Act
    MyObject Result = Service.Get (MyConstraint);


    // Assert
    Assert.AreSame (Expected, Result);
    MockRepo.Verify ();

}

I've looked around at some of the other answers but I cannot really make out what I am doing incorrectly (admittedly a "noob" with Moq).我环顾了其他一些答案,但我无法真正弄清楚我做错了什么(诚然,Moq 是“菜鸟”)。 I have come to the conclusion that this is going to be a pain but I have a lot of tests like this coming up and want to get solid now instead of drowning later.我得出的结论是,这将是一种痛苦,但我有很多这样的测试即将到来,我想现在变得稳固而不是以后淹死。

Is the only option to encapsulate the lambda expression inside of an object and pass in the repository and have it execute the query?将 lambda 表达式封装在 object 中并传入存储库并让它执行查询的唯一选择是什么? I don't want to change my code just for my testing environment, but I don't want to waste time trying to bend this thing to my will, either.我不想仅仅为了我的测试环境而改变我的代码,但我也不想浪费时间试图让这件事服从我的意愿。

It looks like you're trying to mock an extension methods.看起来您正在尝试模拟扩展方法。 You cannot mock extension methods in this way because they're not actually declared on the type that you are mocking.您不能以这种方式模拟扩展方法,因为它们实际上并未在您是 mocking 的类型上声明。

In this case, since youre repository seems to represent a collection of things you should instead substitute a simple hardcoded collection.在这种情况下,由于您的存储库似乎代表了一个东西的集合,您应该替换一个简单的硬编码集合。 It's not clear how exactly you might go about it since you did not provide the source code for IRepository .由于您没有提供IRepository的源代码,因此尚不清楚您可能会如何准确地了解它。

I'd say your best bet is updating your Repository to have something like a FindByConstraint method, where all you pass in is the Constraint and the Repo itself does the FirstOrDefault() .我想说您最好的选择是更新您的Repository以具有类似FindByConstraint方法的东西,您传入的所有内容都是Constraint而 Repo 本身执行FirstOrDefault() I think there's reasonable design reasons for doing this as well as simply to make it easier to test - the search is being carried out case-insensitively and will happily return null, which you could see as decisions the Repo should be making rather than its clients.我认为这样做有合理的设计理由,并且只是为了更容易测试 - 搜索是不区分大小写的,并且会愉快地返回 null,您可以将其视为回购应该做出的决定,而不是它的客户.

I personally take difficulty testing an object to mean there's a flaw in my design, and I think objects being easily testable is something worth striving for.我个人认为很难测试 object 意味着我的设计存在缺陷,我认为易于测试的对象是值得努力的。

This shouldn't need much testing.这应该不需要太多测试。 One correct test will show the code delegating to FirstOrDefault is working, then all subsequent tests are really testing that the logic in the Func constraint is correct which can be done without passing it into the Repository .一个正确的测试将显示委托给FirstOrDefault的代码正在工作,然后所有后续测试都在真正测试Func约束中的逻辑是否正确,无需将其传递到Repository即可完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM