将MOQ属性设置转换为FakeItEasy

时间:2016-12-30 17:30:44

标签: fakeiteasy

其中一位"建设者"我们有以下使用MOQ SetupGet的方法。我尝试重写它以使用FakeItEasy,但似乎没有办法做到这一点,因为WithReturnType只提供通用版本,其中类型必须事先知道。 没有非泛型版本,它采用在运行时确定的实际类型。

当然,我花了整整30分钟。在FakeItEasy上,所以可能有更好的方式......

使用MOQ的原始方法

public void With<TProperty>(Expression<Func<TCommand, TProperty>> expression, TProperty value)
{
      CommandFake.SetupGet(expression).Returns(value);
}

由于我对表达式的了解有限,我尝试重写它以使用FakeItEasy但我无法设置返回值。

    public void With<TProperty>(Expression<Func<TCommand, TProperty>> expression, TProperty value)
    {
        var methodName = string.Empty;

        var e = (LambdaExpression) expression;

        if (e.Body.NodeType == ExpressionType.MemberAccess)
        {
            var memberInfo = ((MemberExpression) e.Body).Member;
            if (memberInfo.MemberType == MemberTypes.Property)
            {
                methodName = "get_" + memberInfo.Name;
            }
            //A.CallTo(CommandFake).Where(call => call.Method.Name == methodName)
            //    .WithReturnType<>()
        }

        //CommandFake.SetupGet(expression).Returns(value);
    }

还有其他方法吗?我没有坚持使用With的这个方法签名。

这也可行

 public void With(Expression<Action<TCommand>> expression)

这样就可以做到了

With(x=>x.someProp=someValue)

1 个答案:

答案 0 :(得分:0)

我不是Moq用户,但看起来SetupGet只是定义了属性get的操作。这似乎相当于FakeItEasy中的A.CallTo

有没有理由不使用

A.CallTo(() => CommandFake.TheProperty).Returns(value));

如果你真的想打电话给

With(f => f.TheProperty, 7);

你可以(从你的例子开始)使用

public void With<TProperty>(Expression<Func<TCommand, TProperty>> expression, TProperty value)
{
    var methodName = string.Empty;

    var e = (LambdaExpression)expression;

    if (e.Body.NodeType == ExpressionType.MemberAccess)
    {
        var memberInfo = ((MemberExpression)e.Body).Member;
        if (memberInfo.MemberType == MemberTypes.Property)
        {
            methodName = "get_" + memberInfo.Name;
        }
        A.CallTo(CommandFake).Where(call => call.Method.Name == methodName)
            .WithReturnType<TProperty>()
            .Returns(value);
    }
}

或者甚至考虑直接使用属性的方法,而不是名称:

public void With<TProperty>(Expression<Func<TCommand, TProperty>> expression, TProperty value)
{
    var e = (LambdaExpression)expression;

    if (e.Body.NodeType == ExpressionType.MemberAccess)
    {
        var memberInfo = ((MemberExpression)e.Body).Member;
        if (memberInfo.MemberType == MemberTypes.Property)
        {
            A.CallTo(CommandFake).Where(call =>
                        call.Method == ((PropertyInfo)memberInfo).GetMethod)
                .WithReturnType<TProperty>()
                .Returns(value);
        }
    }
}