如何在类中模拟两个依赖的方法


interface ISample
{
    int Sum(int a,int b);
    int Multiplication(int x,int a,int b);
}
class Sample
{
    public int Sum(int a,int b)
    {
        return a+b;
    }
    public int Multiplication(int x,int a,int b)
   {
       return x*Sum(a,b);
   }
}

我想测试乘法方法。但是为了测试乘法方法,求和方法需要模拟。我如何模拟Sum方法?有没有可能发生这样的事?

我将独立测试Sum,并且对于乘法测试假设Sum可以工作。如果它适用于求和测试,那么它也应该适用于乘法测试。此外,有些人会认为乘法是如何工作的,不应该通过测试知道。如果你以后有一个不依赖于Sum的不同算法怎么办?

你不模拟你正在测试的类,你模拟它所依赖的类。

如果您真的希望能够独立于Sum()方法测试乘法()方法,则必须将其分离到自己的接口中,并为Sample类提供该接口的实例,以便它可以使用该实例执行求和。

另一种方法是先简单地测试Sum()方法。如果Sum()方法通过了所有的测试,您就可以合理地确定它能正确工作。一旦您知道它可以正确工作,就可以在此基础上测试乘法()方法。

正如其他人所说,您可以使用单独的接口。例如

interface ISum{
   int Sum(int a, int b);
}
interface ISample
{
    int Multiplication(int x, int a, int b);
}
public class Sample : ISample
{
   ISum _sum;
    public Sample(ISum sum)
    {
      _sum = sum;
    }
   int Multiplication(int x, int a, int b)
   {
       return x*_sum.Sum(a,b);
   }
}
在你的测试代码中:
[TestFixture]
public class TestSample
{
    [Test]
    public void TestSample()
    {
        var mockSum = new Mock<ISum>();
        mockSum.Setup(); // fill this what you want
        var sampleObj = new SampleObj(mockSum.Object);
        //Do Some Asserts
    }
}

而不是试图"模拟"Multiplication中对Sum的调用,您应该简单地独立测试它,因为对Sum的调用是一个实现细节。但是,如果您的实际代码稍微复杂一些,您可以添加一个重载,它接受Func:

public int Multiplication(int x,int a,int b)
{
    return this.Multiplication(x, a, b, (a, b) => a + b);
}
public int Multiplication(int x,int a,int b, Func<int, int, int> sumFunc)
{
    return x * sumFunc(a, b);
}

您可以在测试中提供您自己的sumFunc实例。

或者,您可以使Sum成为虚拟的,并在您的测试方法中覆盖它,从而需要将其替换为您自己的实现。

另一个建议是显式实现接口-然后你将不得不引入私有函数,这些私有函数可以为每个方法共享和测试。

private int Sum(int a, int b)
{
    return a+b;
}
int ISample.Sum(int a,int b)
{
    return Sum(a,b);
}
int ISample.Multiplication(int x,int a,int b)
{
   return x*Sum(a,b);
}

我使用过的唯一可以完成您所说的任务的工具是mole。如果您使用的是Moq,则不能这样做。但是,无论哪种方式,我建议将您的类作为一个单元进行测试。也就是说,如果您已经为Sum()编写了测试,并且对它的行为感到满意,那么继续为乘法()编写测试,如果它们暴露了问题,则根据需要在Sum()或乘法中修复它们。

最新更新