Moq 验证属性初始化

问题描述 投票:0回答:1

如何使用最小起订量验证初始化调用?我在接口中定义了以下属性:

public string Text { init; }

我想验证是否使用特定参数调用了 init。这可能吗?

c# .net unit-testing moq xunit
1个回答
0
投票

由于

Moq
Action<I>
API 依赖于
VerifySet
setterExpression,我认为当前的 API 不可能实现这一点,因为我们会在那里遇到编译器错误。

但是,我们可以依靠扩展方法中的表达式来规避编译器错误。遵循仍然需要一些验证但通常会起作用的概念证明:

public static class MoqInitExtensions {
    public static void VerifyInit<T, TPropVal>(this Mock<T> mock,
    string propertyName, TPropVal propValue)
    where T : class {
        // TODO: validation checks/ Exceptions etc
        
        var param = Expression.Parameter(typeof(T));
        var prop = Expression.Property(param, propertyName);
        var assign = Expression.Assign(prop, Expression.Constant(propValue));
        var setterLambda = Expression.Lambda<Action<T>>(assign, param);
        var compiled = setterLambda.Compile();
        mock.VerifySet(compiled);
    }
}

public interface I {
    string Text { init; }
}

void Main() {
    var mock = new Mock<I>(); 
    var obj = mock.Object;
    
    // Simulate reflection call for "init" setter
    var setter = typeof(I).GetProperty("Text").SetMethod;
    setter.Invoke(obj, ["hello"]);
    mock.VerifyInit("Text","hello");
    //mock.VerifyInit("Text", "hello12"); // throws
}
© www.soinside.com 2019 - 2024. All rights reserved.