Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Typemock伪造每个父对象的所有实例_C#_Typemock - Fatal编程技术网

C# 使用Typemock伪造每个父对象的所有实例

C# 使用Typemock伪造每个父对象的所有实例,c#,typemock,C#,Typemock,我最近开始使用Typemock,并查看了至少六个现有线程,但似乎找不到确切问题的答案 我有一个从B派生的类C,它本身从a派生。C的实例是我需要测试的,因此需要是真实的。但由于C派生自B和间接的A,我需要在创建C实例时自动伪造这两个类 见下文: class A { protected int methodA() { return 1; } } class B : A { protected int methodB() { r

我最近开始使用Typemock,并查看了至少六个现有线程,但似乎找不到确切问题的答案

我有一个从B派生的类C,它本身从a派生。C的实例是我需要测试的,因此需要是真实的。但由于C派生自B和间接的A,我需要在创建C实例时自动伪造这两个类

见下文:

class A
{
    protected int methodA()
    {
        return 1;
    }
}

class B : A
{
    protected int methodB()
    {
        return 5;
    }
}

class C : B
{
    public int methodC()
    {
        return methodA() * methodB();
    }
}

class Test
{
    public Test()
    {
        A fake_A = Isolate.Fake.AllInstances<A>(Members.ReturnRecursiveFakes, ConstructorWillBe.Ignored);
        Isolate.NonPublic.WhenCalled(fake_A, "methodA").DoInstead((MethodCallContext ctx) =>
            {
                return 2;
            }
        );

        B fake_B = Isolate.Fake.AllInstances<B>(Members.ReturnRecursiveFakes, ConstructorWillBe.Ignored);
        Isolate.NonPublic.WhenCalled(fake_B, "methodB").DoInstead((MethodCallContext ctx) =>
            {
                return 10;
            }
        );

        C c = new C(); // Would expect A and B to be faked automatically since I've faked all instances above. 
        int method_c_val = c.methodC(); // I get back 5, but what I need returned is 20.
    }
}
这是我面临的问题的一个极其简化的版本。这不仅仅是在父类中伪造一两个方法的行为。整个父母的继承权都需要伪造。所以A和B都需要完全伪造,而不是部分伪造

我已经研究过的一个线程是这个线程,但其中的答案指向一个不再可用的地址:


我不熟悉typemock,但是如果您无法得到答案,并且能够控制所讨论的代码并对其进行修改,我可以建议另一种可能的解决方法

使有问题的方法成为虚拟的,使派生类能够重写它们

class A
{
    protected virtual int methodA()
    {
        return 1;
    }
}

class B : A
{
    protected virtual int methodB()
    {
        return 5;
    }
}

class C : B
{
    public int methodC()
    {
        return methodA() * methodB();
    }
}
要单独测试methodC,您可以创建一个从C派生的存根类D,该存根类D覆盖有问题的方法

class D : C
{
    protected override int methodA()
    {
        return 2;
    }

    protected override int methodB()
    {
        return 10;
    }
}
这样,测试将按预期进行

[TestClass]
public class Test
{
    [TestMethod]
    public void TestMethodC()
    {
        //Arrange
        var expected = 20;
        var c = new D();

        //Act
        int actual = c.methodC();

        //Assert
        Assert.AreEqual(expected, actual);
    }
}

我认为,使用typemock,您需要做一些类似的事情,伪造C,只隔离有问题的两个依赖方法,让测试中的方法自然调用。但是我对这个框架还是不太熟悉。

我对typemock不太熟悉,但是如果您无法得到答案,并且能够控制相关代码并对其进行修改,我可以建议另一种可能的解决方法

使有问题的方法成为虚拟的,使派生类能够重写它们

class A
{
    protected virtual int methodA()
    {
        return 1;
    }
}

class B : A
{
    protected virtual int methodB()
    {
        return 5;
    }
}

class C : B
{
    public int methodC()
    {
        return methodA() * methodB();
    }
}
要单独测试methodC,您可以创建一个从C派生的存根类D,该存根类D覆盖有问题的方法

class D : C
{
    protected override int methodA()
    {
        return 2;
    }

    protected override int methodB()
    {
        return 10;
    }
}
这样,测试将按预期进行

[TestClass]
public class Test
{
    [TestMethod]
    public void TestMethodC()
    {
        //Arrange
        var expected = 20;
        var c = new D();

        //Act
        int actual = c.methodC();

        //Assert
        Assert.AreEqual(expected, actual);
    }
}

我认为,使用typemock,您需要做一些类似的事情,伪造C,只隔离有问题的两个依赖方法,让测试中的方法自然调用。但我对该框架也不太熟悉。

正如@Nkosi所建议的,您可以使用:

C c = Isolate.Fake.Instance<C>(Memebers.CallOriginal);
Isoalte.NonPublic.WhenCalled(c,"methodA").WillReturn(2);
Isoalte.NonPublic.WhenCalled(c,"methodB").WillReturn(10);

您伪造了C对象,但如果需要,它的方法仍会调用原始实现,并且您只伪造有问题的方法。

正如@Nkosi建议的,您可以使用:

class D : C
{
    protected override int methodA()
    {
        return 2;
    }

    protected override int methodB()
    {
        return 10;
    }
}
C c = Isolate.Fake.Instance<C>(Memebers.CallOriginal);
Isoalte.NonPublic.WhenCalled(c,"methodA").WillReturn(2);
Isoalte.NonPublic.WhenCalled(c,"methodB").WillReturn(10);

您可以伪造C对象,但如果需要,它的方法仍会调用原始实现,并且您只伪造有问题的方法。

是的,这在您一开始提到的环境中是可行的,但即使如此,创建本质上是一种变通方法的代码仍然很多。这只是一个非常简单的例子。即使我可以编辑A和B的代码,但我不能,A和B的实际类是畸形的。要进行真正的隔离测试,我必须在每个类中使用更多的方法。这就是Typemock的用武之地。它可以让我递归地伪造所有方法的默认原语值,我可以让我的mock在特定的地方展示自定义行为,比如方法。是的,这在您一开始提到的环境中是可行的,但即使这样,也需要大量代码来创建本质上的变通方法。这只是一个非常简单的例子。即使我可以编辑A和B的代码,但我不能,A和B的实际类是畸形的。要进行真正的隔离测试,我必须在每个类中使用更多的方法。这就是Typemock的用武之地。它让我递归地伪造所有方法的默认原始值,我可以让我的模拟在特定的地方显示自定义行为,比如方法。为系统测试而模拟应用程序的某些部分是非常糟糕的,模拟单个对象的某些方面听起来是个糟糕的主意。如果你真的必须这么做,我建议你重构成一个合成模式,你能详细解释一下为什么这是一个糟糕的想法吗?链接到文章,讨论,另一个帖子,博客,什么东西来支持你的声明?不是说我不相信你,但有些例子会有很大帮助…因为你的课程不是为这个目的而设计的。您所拥有的只是一组没有设计模式的方法。推荐四人帮的设计模式书。祝你一切顺利我正在处理遗留代码,这限制了我的选择。我是在评论你在上面发布的内容,而不是我看不到的内容。如果您的实际代码与上面的意图不符,那么解决您的困境的任何讨论都将是无关的——为系统测试而模拟应用程序的各个部分是非常糟糕的,模拟单个对象的各个方面听起来像是一个可怕的想法。如果你真的必须这么做,我建议你重构成一个合成模式,你能这样做吗
class D : C
{
    protected override int methodA()
    {
        return 2;
    }

    protected override int methodB()
    {
        return 10;
    }
}

你能解释一下为什么这是个糟糕的主意吗?链接到文章,讨论,另一个帖子,博客,什么东西来支持你的声明?不是说我不相信你,但有些例子会有很大帮助…因为你的课程不是为这个目的而设计的。您所拥有的只是一组没有设计模式的方法。推荐四人帮的设计模式书。祝你一切顺利我正在处理遗留代码,这限制了我的选择。我是在评论你在上面发布的内容,而不是我看不到的内容。如果您的实际代码与上面的意图不一致,那么任何解决您的困境的讨论都是无关的,因为我已经编辑了我的问题。基本上,这不仅仅是一个伪造两种方法行为的问题……这只是一个例子来证明我已经用fakeAll尝试过的方法不起作用。我面临的实际情况相当复杂,我需要整个A和B的伪造,而不仅仅是部分。是的,但这取决于你想测试什么。在本例中,从基类继承的方法是由对象C调用的,而不是由A或B调用的,因此伪造它们及其方法与C对象无关。基本上,这不仅仅是一个伪造两种方法行为的问题……这只是一个例子来证明我已经用fakeAll尝试过的方法不起作用。我面临的实际情况相当复杂,我需要整个A和B的伪造,而不仅仅是部分。是的,但这取决于你想测试什么。在这种情况下,从基类继承的方法由对象C调用,而不是由A或B调用,因此伪造它们和它们的方法与C对象无关。