Иногда нужно было мне узнать, что тест выкинул исключение определённого типа с определёнными параметрами или сообщением. Воспользовавшись подсказкой ksg71
public class ExpectedExceptionAndMessageAttribute : ExpectedExceptionBaseAttribute
{
private readonly Type expectedType;
private readonly string expectedMessage;
public ExpectedExceptionAndMessageAttribute(Type expectedExceptionType, string expectedExceptionMessage)
{
if (Equals(expectedExceptionType, null))
throw new ArgumentNullException("expectedExceptionType");
if (Equals(expectedExceptionMessage, null))
throw new ArgumentNullException("expectedExceptionMessage");
expectedType = expectedExceptionType;
expectedMessage = expectedExceptionMessage;
}
protected override void Verify(Exception actualException)
{
Microsoft.VisualStudio.TestTools.UnitTesting.
Assert.AreNotEqual(actualException, null);
Microsoft.VisualStudio.TestTools.UnitTesting.
Assert.AreEqual(expectedType, actualException.GetType());
Microsoft.VisualStudio.TestTools.UnitTesting.
Assert.AreEqual(expectedMessage, actualException.Message);
}
}
Далее встал вопрос как его протестировать. В случае когда ожидаемое исключение и сообщения совпадают с реальными всё просто, тест проходит успешно.
[TestMethod]
[ExpectedExceptionAndMessage(typeof(DivideByZeroException), "Attempted to divide by zero.")]
public void ExpectedExceptionAndMessageAllExcpectedTest()
{
throw new DivideByZeroException();
}
Следующей задачей было проверить, что будет если, например, ожидаемое исключение не совпадёт с реальным. Сделал, так:
[TestMethod]
[ExpectedExceptionAndMessage(typeof(ArgumentException), "Value does not fall within the expected range.")]
public void ExpectedExceptionAndMessageMessageIsExcpectedTest()
{
throw new DivideByZeroException();
}
Проблема в том, что исключение генерируется самим атрибутом, который в тестовый метод не входит, поэтому такой тест будет провален. Можно конечно создать экземпляр класса, а потом используя отражение вызвать метод Verify с нужными параметрами. Но я решил для начала поинтересоваться, есть ли ещё способы как-то его протестировать Например, можно ли указать студии, что провал теста означает его удачное прохождение Ну и код поругайте на всякий случай
а чем стандартный ExpectedExceptionAttribute не подходит?
ну если этот нужно протестировать, то как и любой другой тип, пишете тесты конструктора и метода Verify,
до него лучше добраться отнаследовавшись (сделав некий TestableExpectedExceptionAndMessageAttribute)
рефлекшн не удобно, ислючения будут завернутыми в TargetInvocationException
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Re[2]: Как в UnitTest протестировать такой атрибут?
Здравствуйте, ksg71, Вы писали:
K>Здравствуйте, Cynic, Вы писали:
K>а чем стандартный ExpectedExceptionAttribute не подходит? K>ну если этот нужно протестировать, то как и любой другой тип, пишете тесты конструктора и метода Verify, K>до него лучше добраться отнаследовавшись (сделав некий TestableExpectedExceptionAndMessageAttribute) K>рефлекшн не удобно, ислючения будут завернутыми в TargetInvocationException
Зато с рефлекшеном весь тест в 10-ть строк умещается. А TargetInvocationException можно и развернуть, добравшись до InnerException
Я просто думал, что можно ещё как-то это исполнить. Про наследование, что-то не подумал
Здравствуйте, Cynic, Вы писали:
C>Здравствуйте, alex4Zero, Вы писали:
Z>>если цель — протестировать тип исключения и сообщение, можно поступить так: C>Согласен. Только лучше тогда уж так:
C>
Assert.AreEqual(typeof(T), e.GetType()); — бессмысленно. Этим вы тестируете то, что catch в .NET работает правильно.
Обязательно добавьте Assert.Fail после вызова action(); иначе, если исключения не случится — тест будет зеленым, что не верно
Re[4]: Как в UnitTest протестировать такой атрибут?
Здравствуйте, alex4Zero, Вы писали:
Z>Assert.AreEqual(typeof(T), e.GetType()); — бессмысленно. Этим вы тестируете то, что catch в .NET работает правильно. Z>Обязательно добавьте Assert.Fail после вызова action(); иначе, если исключения не случится — тест будет зеленым, что не верно
Z>Assert.AreEqual(typeof(T), e.GetType()); — бессмысленно. Этим вы тестируете то, что catch в .NET работает правильно. Z>Обязательно добавьте Assert.Fail после вызова action(); иначе, если исключения не случится — тест будет зеленым, что не верно
Assert.AreEqual(typeof(T), e.GetType()) — хотя да, это можно оставить на случай, если вы перехватываете базовый тип исключения