gpt4 book ai didi

.net - 使用Rhino Mocks,如何拦截对接口(interface)上单个属性的调用,同时将其他所有内容传递给 “default implementation” ?

转载 作者:行者123 更新时间:2023-12-01 19:31:33 25 4
gpt4 key购买 nike

我有一个带有许多方法和属性的接口(interface) IComplex,我希望创建一个“模拟”,使“Config”属性返回我选择的对象,同时将所有其他调用传递给IComplex 的“真实”实例。

为了让这件事变得更困难,我们仍然使用 C# V2!

最佳答案

据我所知,没有一个功能可以同时配置多个mock方法。您需要指定所有方法以将它们转发到其他实现...

...除非您编写一些反射代码来配置模拟。

这是一些(工作)代码。它使用 C# 3.0,但主要部分是为 C# 2.0 编写的“旧式”Rhino Mocks 内容。

public static class MockExtensions
{

public static void ForwardCalls<T>(this T mock, T original)
{
mock.BackToRecord();
Type mockType = typeof(T);
var methods = mockType.GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Union(mockType.GetInterfaces().SelectMany(x => x.GetMethods(BindingFlags.Public | BindingFlags.Instance)));
foreach (MethodInfo method in methods)
{
List<object> args = new List<object>();
foreach (var arg in method.GetParameters())
{
args.Add(CreateDefaultValue(arg.ParameterType));
}
method.Invoke(mock, args.ToArray());
var myMethod = method;
if (method.ReturnType == typeof(void))
{
LastCall
.IgnoreArguments()
// not Repeat.Any to allow overriding the value
.Repeat.Times(int.MaxValue)
.WhenCalled(call => myMethod.Invoke(original, call.Arguments));
}
else
{
LastCall
.IgnoreArguments()
// not Repeat.Any to allow overriding the value
.Repeat.Times(int.MaxValue)
.WhenCalled(call => call.ReturnValue = myMethod.Invoke(original, call.Arguments))
.Return(CreateDefaultValue(myMethod.ReturnType));
}
}
mock.Replay();
}

private static object CreateDefaultValue(Type type)
{

if (type.IsValueType)
{
return Activator.CreateInstance(type);
}
else
{
return Convert.ChangeType(null, type);
}
}

}

用法:

[TestClass]
public class TestClass()
{
[TestMethod]
public void Test()
{
var mock = MockRepository.GenerateMock<IList<int>>();
List<int> original = new List<int>();

mock.ForwardCalls(original);

mock.Add(7);
mock.Add(8);
Assert.AreEqual(2, mock.Count);
Assert.AreEqual(7, mock[0]);
Assert.AreEqual(8, mock[1]);

//fake Count after ForwardCalls, use Repeat.Any()
mock.Stub(x => x.Count)
.Return(88)
.Repeat.Any(); // repeat any needed to "override" value

// faked count
Assert.AreEqual(88, mock.Count);
}
}

关于.net - 使用Rhino Mocks,如何拦截对接口(interface)上单个属性的调用,同时将其他所有内容传递给 “default implementation” ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4154032/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com