как может издеваться над двумя методами в зависимости от класса - PullRequest
3 голосов
/ 17 декабря 2011
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);
   }
}

Я хочу проверить метод Умножения. Но чтобы проверить метод умножения, суммировать метод нужно с насмешкой. Как мне издеваться над суммой? Возможно ли что то подобное?

Ответы [ 6 ]

4 голосов
/ 17 декабря 2011

Вы не издеваетесь над классом, который тестируете, вы высмеиваете классы, от которых он зависит.

Если вы действительно хотите иметь возможность тестировать метод Multiplication () независимо от метода Sum (), вам придется разделить его на собственный интерфейс и предоставить классу Sample экземпляр этого интерфейса, который он можно использовать для выполнения суммы.

Альтернативой является сначала просто проверить метод Sum (). Если метод Sum () прошел все свои тесты, вы можете быть уверены, что он работает правильно. Как только вы поймете, что он работает правильно, можно использовать эти знания, протестировав метод Multiplication ().

4 голосов
/ 17 декабря 2011

Я бы протестировал Sum независимо, и для тестов умножения предположим, что Sum работает. Если это работает для тестов Суммы, это должно работать и для Умножения. Кроме того, некоторые утверждают, что тестирование не должно знать, как Multiplication делает свое дело. Что, если у вас будет другой алгоритм, который не зависит от суммы?

3 голосов
/ 19 декабря 2011

Как уже говорилось, вы можете использовать отдельные интерфейсы. Например

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
    }

}
2 голосов
/ 17 декабря 2011

Другим предложением является явная реализация интерфейса - тогда вам придется ввести частные функции, которые можно использовать совместно и тестировать для каждого метода.

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);
}
2 голосов
/ 17 декабря 2011

Вместо того, чтобы пытаться «смоделировать» вызов 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 виртуальным и переопределить его в своих методах тестирования, которые требуют его замены вашей собственной реализацией.

1 голос
/ 17 декабря 2011

Единственный инструмент, который я использовал, который может выполнить то, о чем вы говорите, это Родинки . Если вы используете Moq, это не может быть сделано. Но, в любом случае, я бы посоветовал протестировать ваш класс как юнит. То есть, если вы написали тесты для Sum () и удовлетворены его поведением, перейдите к написанию тестов для Multipication () и, если они выявляют проблемы, исправьте их в Sum () или Multiplication, если необходимо.

...