如何嘲笑一个方法调用,需要一个动态对象(How to mock a method call that

2019-06-24 04:51发布

说我有以下几点:

public interface ISession 
{
   T Get<T>(dynamic filter); }
}

我有以下的代码,我想测试一下:

var user1 = session.Get<User>(new {Name = "test 1"});
var user2 = session.Get<User>(new {Name = "test 2"});

我怎么会嘲笑这个电话?

使用起订量,我厌倦了这样做:

var sessionMock = new Mock<ISession>();
sessionMock.Setup(x => x.Get<User>(new {Name = "test 1")).Returns(new User{Id = 1});
sessionMock.Setup(x => x.Get<User>(new {Name = "test 1")).Returns(new User{Id = 2});

而没有工作。 返回的结果为空

我也试着做犀牛制品如下:

var session = MockRepository.GenerateStub<ISession>();
session.Stub(x => x.Get<User>(new {Name = "test 1"})).Return(new User{Id=1});

没有运气无论是。 再次空。

所以,我会怎么做呢?

谢谢,

Answer 1:

可以使用It.Is<object>与反射一起匹配器。 不能在表达式树使用动态的,所以It.Is<dynamic>将无法正常工作,这就是为什么你需要反思的名字来获取你的财产值:

sessionMock
    .Setup(x => x.Get<User>(
        It.Is<object>(d => d.GetPropertyValue<string>("Name") == "test 1")))
    .Returns(new User{Id = 1});
sessionMock
    .Setup(x => x.Get<User>(
        It.Is<object>(d => d.GetPropertyValue<string>("Name") == "test 2")))
    .Returns(new User { Id = 2 });

GetPropertyValue是一个小帮手:

public static class ReflectionExtensions
{
    public static T GetPropertyValue<T>(this object obj, string propertyName)
    {
        return (T) obj.GetType().GetProperty(propertyName).GetValue(obj, null);
    }
}


Answer 2:

MOQ提供It.IsAny<T>该情况下

sessionMock.Setup(x => x.Get<User>(It.IsAny<object>()).Returns(new User());

*动态是任何对象



Answer 3:

首先,匿名对象并不是真正的dynamic

如果使用dynamic状物体

dynamic user1Filter = new ExpandoObject();
user1Filter.Name = "test 1";
var user1 = session.Get<User>(user1Filter);

你可以嘲笑它像

sessionMock.Setup(x => x.Get<User>(DynamicFilter.HasName("test 1")));

通过实现自定义的参数匹配:

static class DynamicFilter
{
    [Matcher] public static object HasName(string name) { return null; }
    public static bool HasName(dynamic filter, string name)
    {
        string passedName = filter.Name; //dynamic expression
        return name.Equals(passedName);
    }
}


文章来源: How to mock a method call that takes a dynamic object