Хотя этот вопрос стареет, а ответ уже предоставлен, я чувствую, что у меня есть хорошее решение, которое делает вещи простыми и читаемыми.
В конце концов, это позволяет нам писать тесты на предварительных условиях просто:
[Test]
public void Test()
{
Assert.That(FailingPrecondition, Violates.Precondition);
}
public void FailingPrecondition() {
Contracts.Require(false);
}
Хорошо, так что идея состоит в том, чтобы предоставить переписчику Code Contracts собственный класс времени исполнения контракта.
Это можно настроить в свойствах сборки в разделе «Пользовательские методы перезаписи» (см. Раздел 7.7 «Руководство по контрактам кода»):
Не забудьте также проверить Call-site Requires Checking
!
Пользовательский класс выглядит примерно так:
public static class TestFailureMethods
{
public static void Requires(bool condition, string userMessage, string conditionText)
{
if (!condition)
{
throw new PreconditionException(userMessage, conditionText);
}
}
public static void Requires<TException>(bool condition, string userMessage, string conditionText) where TException : Exception
{
if (!condition)
{
throw new PreconditionException(userMessage, conditionText, typeof(TException));
}
}
}
Использование пользовательского класса PreconditionException
(в нем нет ничего фантастического!).
Кроме того, мы добавляем небольшой вспомогательный класс:
public static class Violates
{
public static ExactTypeConstraint Precondition => Throws.TypeOf<PreconditionException>();
}
Это позволяет нам писать простые читаемые тесты на нарушения предварительных условий, как показано выше.