表达式<func <t,bool>&gt;的模拟方法参数使用Moq </func <t,bool>

时间:2010-09-07 03:26:12

标签: .net unit-testing mocking moq

我想使用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作为测试框架。

1 个答案:

答案 0 :(得分:6)

使用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);
}

现在,如果您将某些内容更改为实际方法调用的参数,则测试将不再通过,因为只有在参数相同的情况下,mocked方法才会返回预期结果:

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

备注:采用lambda表达式的模拟方法是以前版本中不可用的新功能,我们需要使用It.Is<SomeType>It.IsAny<SomeType>参数约束。