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

时间:2011-12-16 23:17:13

标签: c# unit-testing mocking moq

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方法?有可能是这样的吗?

6 个答案:

答案 0 :(得分:4)

我将独立测试Sum,并且对于乘法测试,假设Sum有效。如果它适用于Sum测试,它也适用于乘法。此外,有些人会争辩说,乘法如何做它的事情不应该被测试所知。如果您以后使用不同的算法而不依赖Sum,该怎么办?

答案 1 :(得分:4)

你没有模拟你正在测试的类,你嘲笑它所依赖的类。

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

另一种方法是首先简单地测试Sum()方法。如果Sum()方法通过了所有测试,则可以合理地确定它是否正常工作。一旦你知道它正常工作,就可以通过测试乘法()方法来建立这些知识。

答案 2 :(得分:3)

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

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
    }

}

答案 3 :(得分:2)

而不是试图“模拟”Sum中对Multiplication的调用,您应该单独测试它,因为对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虚拟并在您的测试方法中覆盖它,并要求将其替换为您自己的实现。

答案 4 :(得分:2)

另一个建议是明确地实现接口 - 然后你必须引入可以为每个方法共享和测试的私有函数。

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);
}

答案 5 :(得分:1)

我用过的唯一可以完成你所谈论的工具是Moles。如果您使用的是Moq,则无法完成。但无论如何,我建议将你的班级作为一个单元进行测试。也就是说,如果您已经为Sum()编写测试并对其行为感到满意,那么继续为Multipication()编写测试,如果他们暴露问题,则根据需要在Sum()或Multiplication中修复它们。 p>