2016-12-19 2 views
3

Представьте себе этот простой сценарий: У меня есть класс с именем MyModel:Как я должен выполнить тестирование нескольких обязательных полей в C#?

public class MyModel 
{ 
    public string Prop01 { get; set; } 
    public string Prop02 { get; set; } 
    public string Prop03 { get; set; } 

    public bool IsValid() 
    { 
     if (String.IsNullOrEmpty(Prop01) || String.IsNullOrEmpty(Prop02) || String.IsNullOrEmpty(Prop03)) 
      return false; 

     return true; 
    } 
} 

As, вы можете увидеть, если какие-либо из свойств на MyModel является нулевым или пустым, метод IsValid() вернется false, другими словами, все поля «требуются».

Я написал некоторые Unit Tests испытать IsValid() метод:

[TestMethod] 
public void MyModel_Invalid_When_Prop01_Is_Null() 
{ 
    var myModel = new MyModel(); 
    Assert.AreEqual(myModel.IsValid(), false); 
} 

[TestMethod] 
public void MyModel_Invalid_When_Prop02_Is_Null() 
{ 
    var myModel = new MyModel(); 
    Assert.AreEqual(myModel.IsValid(), false); 
} 

[TestMethod] 
public void MyModel_Invalid_When_Prop03_Is_Null() 
{ 
    var myModel = new MyModel(); 
    Assert.AreEqual(myModel.IsValid(), false); 
} 

Конечно все эти тесты будут проходить, но я не совсем доволен. Представим себе, что я разработчик, который видел тест MyModel_Invalid_When_Prop01_Is_Null (который был написан другим разработчиком). Я ожидал бы, что просто назначив значение Prop01myModel, тест должен начать сбой. Но, конечно, это не произойдет, поэтому я изменил тесты, чтобы выглядеть следующим образом:

[TestMethod] 
public void MyModel_Invalid_When_Prop01_Is_Null() 
{ 
    var myModel = new MyModel(); 
    myModel.Prop02 = "Some value"; 
    myModel.Prop03 = "Some value"; 

    Assert.AreEqual(myModel.IsValid(), false); 
} 

[TestMethod] 
public void MyModel_Invalid_When_Prop02_Is_Null() 
{ 
    var myModel = new MyModel(); 
    myModel.Prop01 = "Some value"; 
    myModel.Prop03 = "Some value"; 

    Assert.AreEqual(myModel.IsValid(), false); 
} 

[TestMethod] 
public void MyModel_Invalid_When_Prop03_Is_Null() 
{ 
    var myModel = new MyModel(); 
    myModel.Prop01 = "Some value"; 
    myModel.Prop02 = "Some value"; 

    Assert.AreEqual(myModel.IsValid(), false); 
} 

Теперь тесты действительно тестирование, что каждое из свойств заполнены, но если я добавить Prop04 к MyModel , это также обязательное поле, мне нужно будет снова изменить все мои тесты единиц, поэтому я не думаю, что это хорошая идея.

Так что мой вопрос: Как я могу выполнить тестирование нескольких требуемых свойств таким образом, чтобы я уверен, что тест проходит или не проходит из-за этого конкретного свойства, которое я тестирую сейчас? Или, может быть, Должен ли я тестировать эти сценарии?

ответ

5

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

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

[TestMethod] 
public void MyModel_Invalid_When_Prop01_Is_Null() 
{ 
    var myModel = getValidModel(); 
    myModel.Prop01 = null;  
    Assert.AreEqual(myModel.IsValid(), false); 
} 

[TestMethod] 
public void MyModel_Invalid_When_Prop02_Is_Null() 
{ 
    var myModel = getValidModel(); 
    myModel.Prop02 = null; 

    Assert.AreEqual(myModel.IsValid(), false); 
} 

[TestMethod] 
public void MyModel_Invalid_When_Prop03_Is_Null() 
{ 
    var myModel = getValidModel(); 
    myModel.Prop03 = null; 

    Assert.AreEqual(myModel.IsValid(), false); 
} 

MyModel getValidModel() => 
    new MyModel 
    { 
     Prop01 = "Some value", 
     Prop02 = "Some value", 
     Prop03 = "Some value", 
    }; 

Если инициализация модели становится все более сложным, вы можете использовать шаблон строитель. я написал блог-пост об этом, которые могут быть полезны: https://www.kenneth-truyers.net/2013/07/15/flexible-and-expressive-unit-tests-with-the-builder-pattern/

+0

Очень приятно! Спасибо за ответ! –

+0

Рад помочь! * Пожалуйста, поддержите/примите ответ, если это поможет вам – Kenneth

0

На мой взгляд, если isValid() является достаточно важным, чтобы быть методом, то это достаточно важно, чтобы его поведение должно быть испытано.

В какой-то степени простота его логики может усыпить вас чувством, что она не может стоить всей работы. Ну, я понял, но встречный аргумент заключается в том, что кто-то добавляет другое обязательное поле, неспособное обновить isValid() - очень правдоподобная ошибка; и если вы не тестируете поведение, если isValid(), то вы не узнаете до какой-то загадочной ошибки в производстве, где никто не думает искать Prop04 как Null, потому что hey, isValid() возвращает true ...

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

(пардон любой код опечаток, я не компилятором, но я думаю, вы увидите, что я имею в виду ...)

[TestMethod] 
public void MyModel_Invalid_When_Prop01_Is_Null() 
{ 
    var myModel = getMyModelInstance(); 
    myModel.Prop01 = Null; 

    Assert.AreEqual(myModel.IsValid(), false); 
} 

И, конечно, вы» d есть другой метод тестирования, который не устанавливает любое свойство в Null и утверждает, что IsValid() должен возвращать true.

Итак, теперь вы добавляете новое свойство, вы добавляете новый метод тестирования (который вы ожидаете сделать). Вы обновляете помощника для заполнения нового свойства; вам понадобится, чтобы поддерживать «IsValid()» в любом случае. И поэтому ни один из других существующих методов тестирования не нуждается в обновлении.

Смежные вопросы