Автоматическое тестирование методов получения / установки свойств - PullRequest
4 голосов
/ 22 августа 2011

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

protected string _firstname;

public virtual string Firstname
{
    get { return _firstname; }
    set { _firstname = value; }
}

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

public virtual string Firstname
{
    get { return _firstname; }
    set { _firstname = Firstname; }
}

Было бы легко написать или библиотека уже существует для проверки правильности установки / установки этих вспомогательных полей? Это будет выполняться только для свойств с установщиками и (предположительно) вспомогательным полем, которое совпадает с именем свойства, используя подчеркивание в верблюжьем регистре

Ответы [ 3 ]

5 голосов
/ 22 августа 2011

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

public virtual string FirstName { get; set; }

ОБНОВЛЕНИЕ (см. Комментарии, поле поддержки, по-видимому, необходимо): Другая возможность заключается в создании pocos.Простой t4-шаблон 'Person.tt'

<#@ template language="C#" #>
<# var pocos = new [] {
    Tuple.Create("FirstName", "string"), 
    Tuple.Create("LastName", "string"), 
    Tuple.Create("Age", "int")}; #>
public partial class Person {
    <# foreach(var t in pocos) {#>

    protected <#= t.Item2#> _<#= t.Item1.ToLowerInvariant()#>;
    public virtual <#= t.Item2#> <#= t.Item1#>
    {
        get { return _<#= t.Item1.ToLowerInvariant()#>; }
        set { _<#= t.Item1.ToLowerInvariant()#> = value; }
    }
    <#}#>
}

Теперь это, конечно, может принести столько проблем, сколько решит, но на это стоит взглянуть ... возможно:)

2 голосов
/ 22 августа 2011

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

/ get value of property: public double Number
double value = (double)numberPropertyInfo.GetValue(calcInstance, null);

[C#]
// set value of property: public double Number
numberPropertyInfo.SetValue(calcInstance, 10.0, null);

Для вашего примера:

void Main()
{
        const int testValue=5;
    var test = (Test)Activator.CreateInstance(typeof(Test));
    PropertyInfo valuePropertyInfo = typeof(Test).GetProperty("Value");
    valuePropertyInfo.SetValue(test, testValue, null);
    int value = (int)valuePropertyInfo.GetValue(test, null);
    Console.Write(value);   //Assert here instead

}
public class Test
{
private int _value;
public int Value {get {return _value;}  set{_value=Value;}}
}

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

Что вы думаете об этом подходе.

1 голос
/ 22 августа 2011

Gallio / MbUnit имеет верификатор контракта , который делает именно то, что вы ищете.Типичное использование AccessContract следующее:

public class Foo // Dummy reference type.
{
  private readonly int value;
  public int Value { get { return value; } }

  public Foo (int value)
  {
    this.value = value;
  }
}

public class Bar
{
  private Foo foo;

  public Bar(string unusedParameter) { }

  public Foo Foo // A complex property to be tested!
  {
    get { return foo; }
    set
    {
      if (value == null)
        throw new ArgumentNullException("value");
      if (value.Value < 0)
        throw new ArgumentOutOfRangeException();
      if (value.Value == 666)
        throw new ArgumentException("Inferno value strictly forbidden.");

      foo = value;
    }
  }
}

И тестовое устройство, которое использует AccessorContract для запуска различных тестов свойства.

[TestFixture]
public class BarTest
{
  [VerifyContract]
  public readonly IContract AccessorTests = new AccessorContract<Bar, Foo>
  {
      Getter = target => target.Foo,
      Setter = (target, value) => target.Foo = value,
      ValidValues = { new Foo(123), new Foo(456), new Foo(789) },
      AcceptNullValue = false,
      DefaultInstance = () => new Bar("Hello"),
      InvalidValues =
      {
          { typeof(ArgumentOutOfRangeException), new Foo(-123), new Foo(-456) },
          { typeof(ArgumentException), new Foo(666) }
      }
  };
}

Верификатор контракта генерирует следующие модульные тесты:

enter image description here

Посмотрите на тестовый проект MbUnit для дополнительных примеров использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...