使用 Expression> 模拟方法使用最小起订量的参数

发布于 2024-09-17 10:54:07 字数 463 浏览 3 评论 0 原文

我想使用 Moq 来模拟这个接口,

IInterfaceToBeMocked {
IEnumerable<Dude> SearchDudeByFilter(Expression<Func<Dude,bool>> filter);
}

我正在考虑做类似的事情,

_mock.Setup(method => method.SearchDudeByFilter( x=> x.DudeId.Equals(10) && X.Ride.Equals("Harley"))). Returns(_dudes);// _dudes is an in-memory list of dudes.

当我尝试调试需要这种模拟的单元测试时,它说“不允许表达式”指向 lambda。如果有什么区别的话,我使用 xUnit 作为测试框架。

I want to mock this interface using Moq

IInterfaceToBeMocked {
IEnumerable<Dude> SearchDudeByFilter(Expression<Func<Dude,bool>> filter);
}

I was thinking of doing something like

_mock.Setup(method => method.SearchDudeByFilter( x=> x.DudeId.Equals(10) && X.Ride.Equals("Harley"))). Returns(_dudes);// _dudes is an in-memory list of dudes.

When I try to debug the unit test where i need this mocking, it says that "expression is not allowed" pointing towards the lambda. If it makes any difference I am using xUnit as the testing framework.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

微暖i 2024-09-24 10:54:11

对于我来说,以下内容对于 Moq 4.0 Beta

public class Dude 
{
    public int DudeId { get; set; }
    public string Ride { get; set; }
}

public interface IInterfaceToBeMocked 
{
    IEnumerable<Dude> SearchDudeByFilter(Expression<Func<Dude,bool>> filter);
}

和单元测试效果很好:

[TestMethod]
public void TestDudes()
{
    // arrange
    var expectedDudes = new[]
    {
        new Dude(), new Dude()
    };
    var mock = new Mock<IInterfaceToBeMocked>();
    mock.Setup(method => method.SearchDudeByFilter(
        x => x.DudeId.Equals(10) && x.Ride.Equals("Harley"))
    ).Returns(expectedDudes);

    // act
    // Remark: In a real unit test this call will be made implicitly
    // by the object under test that depends on the interface
    var actualDudes = mock.Object.SearchDudeByFilter(
        x => x.DudeId.Equals(10) && x.Ride.Equals("Harley")
    );

    // assert
    Assert.AreEqual(actualDudes, expectedDudes);
}

现在,如果您将某些内容更改为实际方法调用的参数,则测试将不再通过,因为仅当参数相同时,模拟方法才会返回预期结果:

var actualDudes = mock.Object.SearchDudeByFilter(
    x => x.DudeId.Equals(20) && x.Ride.Equals("Honda")
);

备注:采用 lambda 表达式的模拟方法是一项新功能,以前没有在以前的版本中,我们需要使用 It.IsIt.IsAny 参数约束。

The following works fine for me with the Moq 4.0 Beta:

public class Dude 
{
    public int DudeId { get; set; }
    public string Ride { get; set; }
}

public interface IInterfaceToBeMocked 
{
    IEnumerable<Dude> SearchDudeByFilter(Expression<Func<Dude,bool>> filter);
}

and the unit test:

[TestMethod]
public void TestDudes()
{
    // arrange
    var expectedDudes = new[]
    {
        new Dude(), new Dude()
    };
    var mock = new Mock<IInterfaceToBeMocked>();
    mock.Setup(method => method.SearchDudeByFilter(
        x => x.DudeId.Equals(10) && x.Ride.Equals("Harley"))
    ).Returns(expectedDudes);

    // act
    // Remark: In a real unit test this call will be made implicitly
    // by the object under test that depends on the interface
    var actualDudes = mock.Object.SearchDudeByFilter(
        x => x.DudeId.Equals(10) && x.Ride.Equals("Harley")
    );

    // assert
    Assert.AreEqual(actualDudes, expectedDudes);
}

Now if you change something into the argument of actual method call the test will no longer pass because the mocked method will return the expected result only if the argument is the same:

var actualDudes = mock.Object.SearchDudeByFilter(
    x => x.DudeId.Equals(20) && x.Ride.Equals("Honda")
);

Remark: mocking methods that take lambda expressions is a new feature that was not available in previous versions where we need to use It.Is<SomeType> and It.IsAny<SomeType> parameter constraints.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文