使用Typemock

时间:2017-09-03 01:54:43

标签: c# typemock

我最近开始使用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.
    }
}

这是我面临的问题的极简化版本。它不仅仅是在父类中伪造一个或两个方法的行为的问题。整个父母heirarchy需要伪造。所以A和B都需要完全伪造,而不是部分伪造。

我已经看过的其中一个主题是这个,但那里的答案指向一个不再可用的地址:

https://www.typemock.com/answers/11613/mocking-all-instances-of-a-base-class

2 个答案:

答案 0 :(得分:3)

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

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

你伪造了C对象,但是它的方法仍然调用原始实现(如果需要),并且你只假装有问题的方法。

答案 1 :(得分:2)

我不熟悉typemock,但如果你无法得到答案,控制有问题的代码并能够修改它,我可以建议另一种可能的解决方法。

制作问题virtual中的方法,使派生类能够覆盖它们。

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,它会覆盖相关方法。

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来做类似的事情并且只隔离有问题的两个依赖方法,让被测试的方法自然地调用。但我又不熟悉那个框架。