Прикованный Утверждения


Разве не было бы приятно просто цепочка утверждений после вызова метода или это только у меня? Я думала, что это повысит читаемость.

Вместо:

var myObject = _objectService.GetRandomObject();
Trace.Assert(myObject!=null);

это будет так:

_objectService.GetRandomObject().NeverNull();

с помощью метода расширения, определяемый как

namespace System
{
    public static class AssertionExtensions
    {
        public static T NeverNull<T>(this T obj) 
            where T : class
        {
            Trace.Assert(obj != null);
            return obj;
        }
    }
}

Мы могли бы сделать расширения для некоторых из самых распространенных утверждений:

public static T Never<T>(this T obj, bool condition) 
    where T : class
{
    Trace.Assert(!condition);
    return obj;
}

public static T Always<T>(this T obj, bool condition) 
    where T : class
{
    Trace.Assert(condition);
    return obj;
}

Если кто-то предпочитает исключения утверждает, что это тоже возможно.



597
3
задан 17 октября 2011 в 02:10 Источник Поделиться
Комментарии
3 ответа

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

Contract.Requires(customer.Age > 0);
Contract.Requires(!string.IsNullOrWhitespace(customer.Name));
Contract.Requires(customer.RegisteredProduct.Any());
Contract.Ensures(Contract.Result<SupportTicket> != null);

Он может сделать несколько вещей, что методы расширения не может сделать:


  • Показать вам исходный код тестируемого выражения (хотя FluentAssertions может приблизительно, что с помощью выражений, он имеет тот недостаток, что производительность и ограничения, используя свои пользовательские методы сравнения (или более подробного лямбды) в отличие от простых логических выражений оценивали (как в отладке.Утверждать(...))

  • Проанализировать заявления на возврат ценностей, независимо от того, сколько возвращения заявления у вас в вашем методе.

  • Предоставлять дополнительные метаданные о методе, с помощью инструментов (так что IntelliSense показывает контрактов).

  • Применить контракт к интерфейсу, где все исполнители автоматически наследуют утверждения.

  • Выполнять во время компиляции проверки договора, если вы используете Premium и Ultimate версиях Visual студии. Редактирования: версия 1.5 теперь также поддерживают профессиональные издания.

3
ответ дан 21 октября 2011 в 06:10 Источник Поделиться

Похоже, вы пытаетесь заново изобрести превосходный FluentAssertions библиотека..

2
ответ дан 17 октября 2011 в 08:10 Источник Поделиться

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

Как преимуществом использования этом случае вы получите максимальный эффект от дженериков и flexiblility использования для утверждений библиотеки статические функции, таким образом, может быть использован с структурами и другие типы также. Кроме того, я снял сословных ограничений, потому что есть уже зеркальные функции для типов значений в AssertionContracts статический класс.

Я полагаю, что лучше использовать Функ, Функ функции ссылок, где это уместно, как в этом примере (с использованием функции расширения и анонимные функции):

    public void ProcessQuery(Query obj, QueryParameter parameter)
{
obj
.AssertNotNull()
.AssertIsNotNullOrWhitespace((o) => o.SQLText)
.AssertNull((o) => o.QueryResults)
.AssertNotNull((o) => o.QueryParameters)
.AssertPositive((o) => o.QueryParameters.Length)
.AssertEquals((o) => o.QueryParameters[0].Name, parameter.Name);

AssertionContracts.AssertTrue(() => obj != null);
AssertionContracts.AssertIsNotNullOrWhitespace(() => obj.SQLText);
AssertionContracts.AssertNull(() => obj.QueryResults);
AssertionContracts.AssertNotNull(() => obj.QueryParameters);
AssertionContracts.AssertPositive(() => obj.QueryParameters.Length);
AssertionContracts.AssertEquals(() => obj.QueryParameters[0].Name, parameter.Name);
}

или вот это:

public class SmtpServerAddress 
{
public string UNC { get; set; }
public long UID { get; set; }
}
public class SmtpClient
{
public SmtpServerAddress Server { get; private set; }

public SmtpClient(SmtpServerAddress smtpServer)
{
AssertionContracts.ThrowOnTrue<ArgumentNullException>(() => smtpServer == null);
Server = smtpServer;
}
public SmtpClient(SmtpServerAddress smtpServer, bool dummy1, bool dummy2)
{
smtpServer
.RequireNotNull()
.RequireIsNullOrWhitespace((obj) => obj.UNC)
.RequireEqualsZero((obj) => obj.UID);
Server = smtpServer;
}
}

Исходный код:

public static class AssertionContracts
{
private static class Exceptions<U> where U : Exception, new()
{
public static T ThrowOnTrue<T>(T obj, Func<T, bool> function, params object[] args)
{
if (function(obj) == true)
{
Throw(obj, args);
}
return obj;
}
public static T ThrowOnFalse<T>(T obj, Func<T, bool> function, params object[] args)
{
if (function(obj) == false)
{
Throw(obj, args);
}
return obj;
}
public static void Throw<T>(T obj, params object[] args)
{
throw CreateException(obj, args);
}
private static U CreateException<T>(T obj, params object[] args)
{
return (U)Activator.CreateInstance(typeof(U), args);
}
}
public class ContractException : Exception
{
public ContractException() : base() { }
public ContractException(string message) : base(message) { }
protected ContractException(SerializationInfo info, StreamingContext context) : base(info, context) { }
public ContractException(string message, Exception innerException) : base(message, innerException) { }
}
public static T ThrowOnTrue<T, U>(this T obj, Func<T, bool> function, params object[] args) where U : Exception, new()
{
return AssertionContracts.Exceptions<ContractException>.ThrowOnTrue(obj, function);
}
public static T ThrowOnFalse<T, U>(this T obj, Func<T, bool> function, params object[] args) where U : Exception, new()
{
return AssertionContracts.Exceptions<ContractException>.ThrowOnFalse(obj, function);
}
public static void Throw<T, U>(this T obj, Func<T, bool> function, U ex) where U : Exception
{
AssertionContracts.Exceptions<ContractException>.Throw(obj, function);
}
public static T NoThrowContractException<T>(this T obj, Func<T, bool> function)
{
return AssertionContracts.Exceptions<ContractException>.ThrowOnTrue(obj, function);
}
public static T ThrowContractException<T>(this T obj, Func<T, bool> function)
{
return AssertionContracts.Exceptions<ContractException>.ThrowOnFalse(obj, function);
}
public static T AssertTrue<T>(this T obj, Func<T, bool> function)
{
Trace.Assert(function(obj) == true);
return obj;
}
public static T AssertFalse<T>(this T obj, Func<T, bool> function)
{
Trace.Assert(function(obj) == false);
return obj;
}
public static T AssertIsNullOrEmpty<T>(this T obj, Func<T, string> function)
{
Trace.Assert(string.IsNullOrEmpty(function(obj)));
return obj;
}
public static T AssertIsNullOrWhitespace<T>(this T obj, Func<T, string> function)
{
Trace.Assert(string.IsNullOrWhiteSpace(function(obj)));
return obj;
}
public static T AssertIsNotNullOrEmpty<T>(this T obj, Func<T, string> function)
{
Trace.Assert(!string.IsNullOrEmpty(function(obj)));
return obj;
}
public static T AssertIsNotNullOrWhitespace<T>(this T obj, Func<T, string> function)
{
Trace.Assert(!string.IsNullOrWhiteSpace(function(obj)));
return obj;
}
public static T AssertEquals<T, U>(this T obj, Func<T, U> function, U value)
{
Trace.Assert(object.Equals(function(obj), value));
return obj;
}
public static T AssertNotEquals<T, U>(this T obj, Func<T, U> function, U value)
{
Trace.Assert(!object.Equals(function(obj), value));
return obj;
}
public static T AssertDefault<T, U>(this T obj, Func<T, U> function)
{
Trace.Assert(object.Equals(function(obj), default(U)));
return obj;
}
public static T AssertNonDefault<T, U>(this T obj, Func<T, U> function)
{
Trace.Assert(!object.Equals(function(obj), default(U)));
return obj;
}
public static T AssertNotNull<T, U>(this T obj, Func<T, U> function)
{
Trace.Assert(!object.Equals(function(obj), default(U)));
return obj;
}
public static T AssertNotNull<T>(this T obj)
{
Trace.Assert(!object.Equals(obj, default(T)));
return obj;
}
public static T AssertNull<T, U>(this T obj, Func<T, U> function)
{
Trace.Assert(object.Equals(function(obj), default(U)));
return obj;
}
public static T AssertNull<T>(this T obj)
{
Trace.Assert(object.Equals(obj, default(T)));
return obj;
}
public static T AssertPositive<T>(this T obj, Func<T, int> function)
{
Trace.Assert(function(obj) > 0);
return obj;
}
public static T AssertPositive<T>(this T obj, Func<T, long> function)
{
Trace.Assert(function(obj) > 0);
return obj;
}
public static T AssertNegative<T>(this T obj, Func<T, int> function)
{
Trace.Assert(function(obj) < 0);
return obj;
}
public static T AssertNegative<T>(this T obj, Func<T, long> function)
{
Trace.Assert(function(obj) < 0);
return obj;
}
public static T AssertEqualsZero<T>(this T obj, Func<T, int> function)
{
Trace.Assert(function(obj) == 0);
return obj;
}
public static T AssertEqualsZero<T>(this T obj, Func<T, long> function)
{
Trace.Assert(function(obj) == 0);
return obj;
}
public static T AssertNotEqualsZero<T>(this T obj, Func<T, int> function)
{
Trace.Assert(function(obj) != 0);
return obj;
}
public static T AssertNotEqualsZero<T>(this T obj, Func<T, long> function)
{
Trace.Assert(function(obj) != 0);
return obj;
}
public static T AssertGreaterThan<T>(this T obj, Func<T, int> function, int value)
{
Trace.Assert(function(obj) > value);
return obj;
}
public static T AssertGreaterThan<T>(this T obj, Func<T, long> function, long value)
{
Trace.Assert(function(obj) > value);
return obj;
}
public static T AssertLessThan<T>(this T obj, Func<T, int> function, int value)
{
Trace.Assert(function(obj) < value);
return obj;
}
public static T AssertLessThan<T>(this T obj, Func<T, long> function, long value)
{
Trace.Assert(function(obj) < value);
return obj;
}
public static T AssertGreaterOrEqualsThan<T>(this T obj, Func<T, int> function, int value)
{
Trace.Assert(function(obj) >= value);
return obj;
}
public static T AssertGreaterOrEqualsThan<T>(this T obj, Func<T, long> function, long value)
{
Trace.Assert(function(obj) >= value);
return obj;
}
public static T AssertLessOrEqualsThan<T>(this T obj, Func<T, int> function, int value)
{
Trace.Assert(function(obj) <= value);
return obj;
}
public static T AssertLessOrEqualsThan<T>(this T obj, Func<T, long> function, long value)
{
Trace.Assert(function(obj) <= value);
return obj;
}
public static T AssertGreaterOrEqualsZero<T>(this T obj, Func<T, int> function)
{
Trace.Assert(function(obj) >= 0);
return obj;
}
public static T AssertGreaterOrEqualsZero<T>(this T obj, Func<T, long> function, long value)
{
Trace.Assert(function(obj) >= 0);
return obj;
}
public static T AssertLessOrEqualsZero<T>(this T obj, Func<T, int> function)
{
Trace.Assert(function(obj) <= 0);
return obj;
}
public static T AssertLessOrEqualsZero<T>(this T obj, Func<T, long> function)
{
Trace.Assert(function(obj) <= 0);
return obj;
}
public static T RequireTrue<T>(this T obj, Func<T, bool> function)
{
return obj.ThrowContractException((o) => function(obj) == true);
}
public static T RequireFalse<T>(this T obj, Func<T, bool> function)
{
return obj.ThrowContractException((o) => function(obj) == false);
}
public static T RequireIsNullOrEmpty<T>(this T obj, Func<T, string> function)
{
return obj.ThrowContractException((o) => string.IsNullOrEmpty(function(obj)));
}
public static T RequireIsNullOrWhitespace<T>(this T obj, Func<T, string> function)
{
return obj.ThrowContractException((o) => string.IsNullOrWhiteSpace(function(obj)));
}
public static T RequireIsNotNullOrEmpty<T>(this T obj, Func<T, string> function)
{
return obj.ThrowContractException((o) => !string.IsNullOrEmpty(function(obj)));
}
public static T RequireIsNotNullOrWhitespace<T>(this T obj, Func<T, string> function)
{
return obj.ThrowContractException((o) => !string.IsNullOrWhiteSpace(function(obj)));
}
public static T RequireEquals<T, U>(this T obj, Func<T, U> function, U value)
{
return obj.ThrowContractException((o) => object.Equals(function(obj), value));
}
public static T RequireEquals<T, U>(this T obj, T value)
{
return obj.ThrowContractException((o) => object.Equals(obj, value));
}
public static T RequireNotEquals<T, U>(this T obj, Func<T, U> function, U value)
{
return obj.ThrowContractException((o) => !object.Equals(function(obj), value));
}
public static T RequireNotEquals<T, U>(this T obj, T value)
{
return obj.ThrowContractException((o) => !object.Equals(obj, value));
}
public static T RequireDefault<T, U>(this T obj, Func<T, U> function)
{
return obj.ThrowContractException((o) => object.Equals(function(obj), default(U)));
}
public static T RequireDefault<T>(this T obj)
{
return obj.ThrowContractException((o) => object.Equals(obj, default(T)));
}
public static T RequireNonDefault<T, U>(this T obj, Func<T, U> function)
{
return obj.ThrowContractException((o) => !object.Equals(function(obj), default(U)));
}
public static T RequireNonDefault<T, U>(this T obj)
{
return obj.ThrowContractException((o) => !object.Equals(obj, default(T)));
}
public static T RequireNotNull<T, U>(this T obj, Func<T, U> function)
{
return obj.ThrowContractException((o) => !object.Equals(function(obj), default(U)));
}
public static T RequireNotNull<T>(this T obj)
{
return obj.ThrowContractException((o) => !object.Equals(obj, default(T)));
}
public static T RequireNull<T, U>(this T obj, Func<T, U> function)
{
return obj.ThrowContractException((o) => object.Equals(function(obj), default(U)));
}
public static T RequireNull<T>(this T obj)
{
return obj.ThrowContractException((o) => object.Equals(obj, default(T)));
}
public static T RequirePositive<T>(this T obj, Func<T, int> function)
{
return obj.ThrowContractException((o) => function(obj) > 0);
}
public static T RequirePositive<T>(this T obj, Func<T, long> function)
{
return obj.ThrowContractException((o) => function(obj) > 0);
}
public static T RequireNegative<T>(this T obj, Func<T, int> function)
{
return obj.ThrowContractException((o) => function(obj) < 0);
}
public static T RequireNegative<T>(this T obj, Func<T, long> function)
{
return obj.ThrowContractException((o) => function(obj) < 0);
}
public static T RequireEqualsZero<T>(this T obj, Func<T, int> function)
{
return obj.ThrowContractException((o) => function(obj) == 0);
}
public static T RequireEqualsZero<T>(this T obj, Func<T, long> function)
{
return obj.ThrowContractException((o) => function(obj) == 0);
}
public static T RequireNotEqualsZero<T>(this T obj, Func<T, int> function)
{
return obj.ThrowContractException((o) => function(obj) != 0);
}
public static T RequireNotEqualsZero<T>(this T obj, Func<T, long> function)
{
return obj.ThrowContractException((o) => function(obj) != 0);
}
public static T RequireGreaterThan<T>(this T obj, Func<T, int> function, int value)
{
return obj.ThrowContractException((o) => function(obj) > value);
}
public static T RequireGreaterThan<T>(this T obj, Func<T, long> function, long value)
{
return obj.ThrowContractException((o) => function(obj) > value);
}
public static T RequireLessThan<T>(this T obj, Func<T, int> function, int value)
{
return obj.ThrowContractException((o) => function(obj) < value);
}
public static T RequireLessThan<T>(this T obj, Func<T, long> function, long value)
{
return obj.ThrowContractException((o) => function(obj) < value);
}
public static T RequireGreaterOrEqualsThan<T>(this T obj, Func<T, int> function, int value)
{
return obj.ThrowContractException((o) => function(obj) >= value);
}
public static T RequireGreaterOrEqualsThan<T>(this T obj, Func<T, long> function, long value)
{
return obj.ThrowContractException((o) => function(obj) >= value);
}
public static T RequireLessOrEqualsThan<T>(this T obj, Func<T, int> function, int value)
{
return obj.ThrowContractException((o) => function(obj) <= value);
}
public static T RequireLessOrEqualsThan<T>(this T obj, Func<T, long> function, long value)
{
return obj.ThrowContractException((o) => function(obj) <= value);
}
public static T RequireGreaterOrEqualsZero<T>(this T obj, Func<T, int> function)
{
return obj.ThrowContractException((o) => function(obj) >= 0);
}
public static T RequireGreaterOrEqualsZero<T>(this T obj, Func<T, long> function, long value)
{
return obj.ThrowContractException((o) => function(obj) >= 0);
}
public static T RequireLessOrEqualsZero<T>(this T obj, Func<T, int> function)
{
return obj.ThrowContractException((o) => function(obj) <= 0);
}
public static T RequireLessOrEqualsZero<T>(this T obj, Func<T, long> function)
{
return obj.ThrowContractException((o) => function(obj) <= 0);
}
public static void ThrowOnFalse<U>(Func<bool> function, params object[] args) where U : Exception, new()
{
if (function() == false)
{
throw (U)Activator.CreateInstance(typeof(U), args);
}
}
public static void ThrowOnTrue<U>(Func<bool> function, params object[] args) where U : Exception, new()
{
if (function() == true)
{
throw (U)Activator.CreateInstance(typeof(U), args);
}
}
public static void Throw<U>(Func<bool> function, U ex) where U : Exception
{
if (function() == false)
{
throw ex;
}
}
public static void AssertTrue(Func<bool> function)
{
Trace.Assert(function() == true);
}
public static void AssertFalse(Func<bool> function)
{
Trace.Assert(function() == false);
}
public static void AssertIsNullOrEmpty(Func<string> function)
{
Trace.Assert(string.IsNullOrEmpty(function()));
}
public static void AssertIsNullOrWhitespace(Func<string> function)
{
Trace.Assert(string.IsNullOrWhiteSpace(function()));
}
public static void AssertIsNotNullOrEmpty(Func<string> function)
{
Trace.Assert(!string.IsNullOrEmpty(function()));
}
public static void AssertIsNotNullOrWhitespace(Func<string> function)
{
Trace.Assert(!string.IsNullOrWhiteSpace(function()));
}
public static void AssertEquals<U>(Func<U> function, U value)
{
Trace.Assert(object.Equals(function(), value));
}
public static void AssertNotEquals<U>(Func<U> function, U value)
{
Trace.Assert(!object.Equals(function(), value));
}
public static void AssertDefault<U>(Func<U> function)
{
Trace.Assert(object.Equals(function(), default(U)));
}
public static void AssertNonDefault<U>(Func<U> function)
{
Trace.Assert(!object.Equals(function(), default(U)));
}
public static void AssertNotNull<U>(Func<U> function)
{
Trace.Assert(!object.Equals(function(), default(U)));
}
public static void AssertNull<U>(Func<U> function)
{
Trace.Assert(object.Equals(function(), default(U)));
}
public static void AssertPositive(Func<int> function)
{
Trace.Assert(function() > 0);
}
public static void AssertPositive(Func<long> function)
{
Trace.Assert(function() > 0);
}
public static void AssertNegative(Func<int> function)
{
Trace.Assert(function() < 0);
}
public static void AssertNegative(Func<long> function)
{
Trace.Assert(function() < 0);
}
public static void AssertEqualsZero(Func<int> function)
{
Trace.Assert(function() == 0);
}
public static void AssertEqualsZero(Func<long> function)
{
Trace.Assert(function() == 0);
}
public static void AssertNotEqualsZero(Func<int> function)
{
Trace.Assert(function() != 0);
}
public static void AssertNotEqualsZero(Func<long> function)
{
Trace.Assert(function() != 0);
}
public static void AssertGreaterThan(Func<int> function, int value)
{
Trace.Assert(function() > value);
}
public static void AssertGreaterThan(Func<long> function, long value)
{
Trace.Assert(function() > value);
}
public static void AssertLessThan(Func<int> function, int value)
{
Trace.Assert(function() < value);
}
public static void AssertLessThan(Func<long> function, long value)
{
Trace.Assert(function() < value);
}
public static void AssertGreaterOrEqualsThan(Func<int> function, int value)
{
Trace.Assert(function() >= value);
}
public static void AssertGreaterOrEqualsThan(Func<long> function, long value)
{
Trace.Assert(function() >= value);
}
public static void AssertLessOrEqualsThan(Func<int> function, int value)
{
Trace.Assert(function() <= value);
}
public static void AssertLessOrEqualsThan(Func<long> function, long value)
{
Trace.Assert(function() <= value);
}
public static void AssertGreaterOrEqualsZero(Func<int> function)
{
Trace.Assert(function() >= 0);
}
public static void AssertGreaterOrEqualsZero(Func<long> function, long value)
{
Trace.Assert(function() >= 0);
}
public static void AssertLessOrEqualsZero<T>(Func<int> function)
{
Trace.Assert(function() <= 0);
}
public static void AssertLessOrEqualsZero(Func<long> function)
{
Trace.Assert(function() <= 0);
}
}

1
ответ дан 17 октября 2011 в 04:10 Источник Поделиться