5

是否有可能用 Microsoft Fakes 隔离/替换类的构造函数?

找到了 Mole(Fakes 的前身)的示例:http: //thecurlybrace.blogspot.co.at/2011/11/how-do-i-detour-mole-type-constructor.html

我尝试过这样的构造

ShimStreamReader.Constructor = @this => ShimStreamReader.ConstructorString(@this, "Test");

但它说 get 访问器丢失。为了澄清,更换类似的东西会很好

new StreamReader("filename")

像这样的静态输入

new StreamReader(new MemoryStream(Encoding.Default.GetBytes("33\r\n1\r\n16\r\n5\r\n7")))

这样我就不必模拟 Read、ReadLine 等。

4

2 回答 2

6
using (ShimsContext.Create())
{
    ShimStreamReader.ConstructorString = 
        delegate(StreamReader @this, string @string)
        {
            var shim = new ShimStreamReader(@this);
            shim.Read = () => 42;
        };

    var target = new StreamReader("MeaningOfLife.txt");
    Assert.AreEqual(42, target.Read());
}
于 2012-10-13T00:03:28.630 回答
4

可以通过反射替换和调用不同的构造函数:

“因此,当您替换构造函数时,您应该在构造函数中进行所有初始化。对于 StreamReader 构造函数可能是不可能的,因为您不知道原始构造函数如何在内部初始化对象并且您无权访问私有对象的成员。

所以,我们可以使用反射来调用原始构造函数来初始化对象,然后使用它。” - 请参阅http://social.msdn.microsoft.com上的 Vikram Agrawals 回答

所以关于我的问题的代码看起来像这样:

ShimStreamReader.ConstructorString = (@this, value) =>
{
    ConstructorInfo constructor = typeof (StreamReader).GetConstructor(new[] {typeof (Stream)});
    constructor.Invoke(@this, new object[] {new MemoryStream(Encoding.Default.GetBytes("33\r\n1\r\n16\r\n5\r\n7"))});
};
于 2012-10-26T13:08:33.360 回答