У меня есть несколько базовых классов с методами клонирования:
public class SimpleClass
{
public int ValueA { get; set; }
public string ValueB { get; set; }
public ulong ValueC { get; set; }
public SimpleClass TypedClone()
{
var item = new SimpleClass
{
ValueA = this.ValueA,
ValueB = this.ValueB,
ValueC = this.ValueC
};
return item;
}
}
Мне нужен модульный тест, который сообщит мне, если я добавлю ValueD, но забуду добавить его в метод Clone. Моей первой попыткой было использование Moq и его метода VerifyGet, чтобы убедиться, что к каждому свойству обращались.
public void GenericCloneTest()
{
var mock = new Mock<SimpleClass>();
var c = mock.Object.GenericClone();
var properties = typeof(SimpleClass).GetProperties();
foreach (var property in properties)
{
var expression = Expression.Property(
Expression.Parameter(typeof(SimpleClass), "c"),
property);
var type = Expression.GetFuncType(typeof (SimpleClass),
property.PropertyType);
var actionExpression = Expression.Lambda(type, expression,
Expression.Parameter(typeof(SimpleClass), "c"));
mock.VerifyGet<object>
((Expression<Func<SimpleClass,object>>)actionExpression);
}
}
Это не работает, потому что метод VerifyGet должен знать тип возвращаемого метода доступа к свойству, и я не могу найти какой-либо способ вставить его во время выполнения (вы заметите мою неудачную попытку использовать "объект") который разбился и сгорел).
Я даже не уверен, что использование Moq - хорошая идея, это была только моя первая.
ОБНОВЛЕНИЕ: не имея быстрого и простого универсального способа тестирования метода клонирования, я остановился на написании специфических для каждого типа тестов. Это все еще оставляет меня с проблемой знания, когда свойства были добавлены. Я решил добавить это в мои тесты клонов:
var signature = typeof (Connection)
.GetProperties()
.Select(p => p.Name)
.Aggregate(
new StringBuilder(),
(builder, name) =>
builder.Append(name)).ToString();
Assert.AreEqual(
"DataSessionStateDataTechnologyBytesReceivedBytesSentDuration",
signature);
Если я добавлю свойство, тест не пройден. От меня по-прежнему зависит, насколько я ответственен, чтобы исправить оставшуюся часть теста, когда совпадение сигнатур окажется неудачным.