Проверка, если аргумент брошен в юнит-тестах - PullRequest
3 голосов
/ 05 января 2012

Я работаю над юнит-тестами для приложения, у которого есть конструктор, который принимает три значения в качестве аргументов. Числа должны быть 0 или выше, и сейчас я пишу юнит-тест для конструктора, который выдает исключение, если это не так.

Что я не могу понять, так это то, как я должен написать после «Утвердить», чтобы определить это так, чтобы тест проходил, если в конструктор передаются недопустимые числа. Заранее спасибо.

РЕДАКТИРОВАТЬ: я использую MSTest Framework

   public void uniqueSidesTest2()
    {
        try {
            Triangle_Accessor target = new Triangle_Accessor(0, 10, 10);
        }
        catch (){
            Assert // true (pass the test)
            return;
        }

        Assert. // false (test fails)
    }

// Из кода ...

    public Triangle(double a, double b, double c) {
        if ((a <= 0) || (b <= 0) || (c <= 0)){
            throw new ArgumentException("The numbers must higher than 0.");
        }
        sides = new double[] { a, b, c };
    }

Ответы [ 6 ]

9 голосов
/ 05 января 2012

Прежде всего, вы должны бросить ArgumentOutOfRangeException, а не просто ArgumentException.

Во-вторых, ваш модульный тест должен ожидать исключения, например:

[ExpectedException(typeof(ArgumentOutOfRangeException))]
public static void MyUnitTestForArgumentA()
{
    ...
}

Итак, вам нужно создать отдельные модульные тесты - по одному для каждого аргумента - которые проверяют, выбрасывает ли метод правильное исключение, когда аргумент выходит за пределы диапазона.

4 голосов
/ 05 января 2012

Нет необходимости использовать блок try catch.Используя NUnit или инфраструктуру MSTest, вы можете использовать атрибут в объявлении метода тестирования, чтобы указать, что вы ожидаете исключения.

MSTest

 [TestMethod]
 [ExpectedException(typeof(ArgumentException))]
 public void uniqueSidesTest2()
2 голосов
/ 05 января 2012

Если у вас нет nunit (или другой интегрированной среды, в которую встроена эта поддержка, вы можете использовать вспомогательный метод следующего типа

 public static void ThrowsExceptionOfType<T>(Action action) where T: Exception
    {
        try
        {
            action();
        }
        catch (T)
        {
            return;
        }
        catch (Exception exp)
        {
            throw new Exception(string.Format("Assert failed. Expecting exception of type {0} but got {1}.", typeof(T).Name, exp.GetType().Name));
        }

        throw new Exception(string.Format("Assert failed. Expecting exception of type {0} but no exception was thrown.", typeof(T).Name));
    }

Ваш тест будет выглядеть следующим образом

AssertHelper.ThrowsExceptionOfType<ArgumentException>( 
    () => 
    {
        new Triangle_Accessor(0, 10, 10);
    });
2 голосов
/ 05 января 2012

Возможно, это не лучшее решение, но если я проверяю, чтобы убедиться, что выдается исключение, я сделаю что-то вроде следующего:

public void uniqueSidesTest2()
{
    try {
        Triangle_Accessor target = new Triangle_Accessor(0, 10, 10);
        Assert.Fail("An exception was not thrown for an invalid argument.");
    }
    catch (ArgumentException ex){
        //Do nothing, test passes if Assert.Fail() was not called
    }
}

Поскольку ваш вызов конструктора должен выдавать ошибку, если он когда-либо попадет на вторую строку (строку Assert.Fail ()), вы знаете, что она не вызвала ошибку правильно.

0 голосов
/ 05 января 2012

Вы не упоминаете, какую платформу вы используете для модульного тестирования, но я думаю, что вы ищете что-то вроде того, что показано здесь:

http://www.nunit.org/index.php?p=exception&r=2.4

0 голосов
/ 05 января 2012

Вам не понадобится Assert в catch (но вы можете захотеть поймать более конкретное исключение, например ArgumentException).

Чтобы всегда терпеть неудачу, существует Assert.Fail .

...