代码之家  ›  专栏  ›  技术社区  ›  Perpetualcoder

使用moq的表达式<func<t,bool>>参数模拟方法

  •  4
  • Perpetualcoder  · 技术社区  · 14 年前

    我想用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 回复  |  直到 14 年前
        1
  •  6
  •   Darin Dimitrov    14 年前

    以下工作对我来说很好 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.Is<SomeType> It.IsAny<SomeType> 参数约束。