Утверждение исключения, выданного из конструктора фиктивного объекта - PullRequest
9 голосов
/ 12 апреля 2011

Предположим: VS2010, .NET 4, C #, NUnit, Moq

Я новичок в TDD и столкнулся с этой проблемой, работая над проектом.

Учитывая класс:

public abstract class MyFileType
{                
    public MyFileType(String fullPathToFile)
    {
        if (!File.Exists(fullPathToFile))
        {
            throw new FileNotFoundException();
        }

        // method continues

    }
}

Я пытаюсь проверить это методом:

[Test]
[ExpectedException(typeof(System.IO.FileNotFoundException))]
public void MyFileType_CreationWithNonexistingPath_ExceptionThrown()
{
    String nonexistingPath = "C:\\does\\not\\exist\\file.ext";
    var mock = new Mock<MyFileType>(nonexistingPath);
}

Тест не пройден, и NUnit сообщает, что исключение не было выдано.

Я нашел раздел в документах NUnit , в котором говорится об утверждении с исключениями, но примеры не были похожи на то, что я пытаюсь сделать. Я все еще начинаю работать с NUnit и Moq, так что могу ошибаться.

UPDATE:

Чтобы прояснить, почему в этом примере используется абстрактный класс, это базовый класс типов файлов серии, где только загрузка и удаление данных будут различаться между подклассами. Сначала я хотел поместить логику открытия / настройки в базовый класс, поскольку он одинаков для всех типов.

Ответы [ 5 ]

5 голосов
/ 13 апреля 2011

Конструктор не будет вызываться, пока вы не ссылаетесь на mock.Object.Это должно вызвать исключение, которое вы ожидаете.

На заметку о том, что обычно конструктор генерирует исключения, отличные от исключений использования (например, различные производные ArgumentException). Большинство разработчиков не ожидают этого.«новый», чтобы бросить исключение, если они не сделали что-то очень неправильное;несуществующий файл - это исключение, которое может на законных основаниях происходить вне контроля программы, поэтому вы можете захотеть сделать этот метод статическим фабричным, а не таким, как «FromFileName».РЕДАКТИРОВАТЬ: Учитывая, что это конструктор базового класса, это не совсем применимо, так что вы можете подумать, где лучше всего установить эту проверку.В конце концов, файл может перестать существовать в любой момент, поэтому может не иметь смысла проверять конструктор (в любом случае вам нужно будет проверить все соответствующие методы).

3 голосов
/ 19 апреля 2012

Я столкнулся с подобной проблемой сегодня. Я решил, используя следующее решение:

[Test]
[ExpectedException(typeof(System.IO.FileNotFoundException))]
public void MyFileType_CreationWithNonexistingPath_ExceptionThrown()
{
    String nonexistingPath = "C:\\does\\not\\exist\\file.ext";
    var mock = new Mock<MyFileType>(nonexistingPath);
    try
    {
        var target = mock.Object;
    }
    catch(TargetInvocationException e)
    {
        if (e.InnerException != null)
        {
            throw e.InnerException;
        }
        throw;
    }
}
3 голосов
/ 13 апреля 2011

Если вы хотите, чтобы класс был абстрактным, мы должны просто реализовать его, как это и должно быть (простота): MSDN: абстрактный класс

Итак, согласившисьс помощью alexanderb), что имитирование, вероятно, здесь не требуется, а также с помощью Stecy в расширении .Throws NUnit Assert, вы можете создать класс в тесте, который вызывает базовый класс следующим образом:

2 голосов
/ 12 апреля 2011

Если вы пытаетесь протестировать класс MyFileType, он выдает исключение, если файл не существует, почему вы создаете макет. Ваш код должен быть простым

[Test]
[ExpectedException(typeof(System.IO.FileNotFoundException))]
public void MyFileType_CreationWithNonexistingPath_ExceptionThrown()
{
    // arrange
    var nonexistingPath = "C:\\does\\not\\exist\\file.ext";

    // act / assert
    var mock = new MyFileType(nonexistingPath);
}
2 голосов
/ 12 апреля 2011

Если вы используете последнюю версию NUnit (вам следует), тогда атрибут ExpectedException устарел.

Вместо этого следует использовать следующее:

var exception = Assert.Throws<FileNotFoundException> (() => new MyFileType (nonExistingPath));
Assert.That (exception, Is.Not.Null);  // Or you can check for exception text...

Нет необходимостииспользуйте насмешку там.На самом деле макет ничего интересного в вашем примере не делает.

...