Если вы делаете TDD, вы должны двигаться небольшими шагами и сосредоточиться на том, что классы должны делать. Вот пример. Вы хотите распечатать несколько отчетов. Сначала (я предполагаю, что вы двигаетесь за пределы) вы разрабатываете класс Report
, который должен печатать себя через Printer
(это только пример). Так вы пишете тест:
[Test]
public void ShouldPrintItself()
{
Mock<IPrinter> printer = new Mock<IPrinter>();
Report report = new Report(printer.Object);
report.Text = "foo";
report.Print();
printer.Verify(p => p.Print("foo"));
}
И вы пишете какую-то реализацию report.Print
метода. Также вы сейчас разрабатываете интерфейс IPrinter. Затем вы понимаете, что принтер иногда может показывать исключения (например, из бумаги). Это ваш случай кстати. Таким образом, вы переименовывать report.Print
способ что-то вроде TryPrint
, изменить первое испытание и создать новый:
[Test]
public void ShouldPrint()
{
Mock<IPrinter> printer = new Mock<IPrinter>();
Report report = new Report(printer.Object);
report.Text = "foo";
Assert.True(report.TryPrint());
printer.Verify(p => p.Print("foo"));
}
[Test]
public void ShouldNotPrint()
{
Mock<IPrinter> printer = new Mock<IPrinter>();
printer.Setup(p => p.Print(It.IsAny<string>())).Throws<Exception>();
Report report = new Report(printer.Object);
report.Text = "foo";
Assert.False(report.TryPrint());
}
И вы вернетесь к TryPrint
методе. Теперь вы добавляете try catch
блок вокруг вызова на принтер и сделать тесты пройдены (то же самое следует делать в вашем приложении):
public bool TryPrint()
{
try
{
_printer.Print(_text);
return true;
}
catch (Exception ex)
{
// of course, log exception
return false;
}
}
Когда вы сделали здесь, вы можете перейти к созданию Printer
. В вашем случае это будут тесты компонентов. Хорошие новости - у вас уже есть интерфейс IPrinter
. Таким образом, вы пишете тесты и проверить, что в некоторых случаях будет сгенерировано исключение:
[Test]
public void ShouldThrowExceptionWhenNoPaperLeft()
{
Printer printer = new Printer();
printer.PagesCount = 0;
Exception ex = Assert.Throws<Exception>(() => printer.Print("foo"));
Assert.That(ex.Message, Is.EqualTo("Out of paper"));
}
И, конечно, вы пишете реализацию компонента, чтобы пройти этот тест. После этого оба вашего класса с блоком try catch
работают так, как ожидалось, и ваш компонент работает как ожидалось, создавая исключения, когда это необходимо.
Не ловить. Или, возможно, исключение. – Zenwalker
Если исключение не обрабатывается блоком 'Catch', то ваш юнит-тест не будет выдавать какое-либо конкретное исключение, но если он будет проверен/обработан, ваш тест пройдет. Не уверен, есть ли какой-либо конкретный способ. – Rahul
Утвердить исключение, тогда тестовый пример не завершится. – Zenwalker