Я пытаюсь сделать модульный тест для класса объекта, который содержит в нем значения с помощью get / sets.
Я понимаю, как вы можете проверить вычисление чисел.
Но как вы тестируете get / sets там, где нет таких методов, как x + y?
Это класс, который мне нужно протестировать:
public class Train
{
//Variables to hold each Trains details. Using different data types for specific entrys when necessary.
private string _trainID;
private string _departure;
private string _destination;
private string _type;
private string _interStop;
private TimeSpan _departureTime;
private string _departureDay;
private bool _sleeperBerth;
private bool _firstClass;
//Get/Set for setting Train ID value.
public string TrainID
{
get { return _trainID; }
set { _trainID = value; }
}
//Get/Set for setting departure value.
public string Departure
{
get { return _departure; }
set { _departure = value; }
}
//Get/Set for setting destination value.
public string Destination
{
get { return _destination; }
set { _destination = value; }
}
//Get/Set for setting type value.
public string Type
{
get { return _type; }
set { _type = value; }
}
//Get/Set for setting Intermediate Stop value.
public string IntermediateStop
{
get { return _interStop; }
set { _interStop = value; }
}
//Get/Set for setting Departure Time value.
public TimeSpan DepartureTime
{
get { return _departureTime; }
set { _departureTime = value; }
}
//Get/Set for setting Departure Day value.
public string DepartureDay
{
get { return _departureDay; }
set { _departureDay = value; }
}
//Get/Set for setting Sleeper Berth value.
public bool SleeperBerth
{
get { return _sleeperBerth; }
set { _sleeperBerth = value; }
}
//Get/Set for setting First Class value.
public bool FirstClass
{
get { return _firstClass; }
set { _firstClass = value; }
}
}
Я также составил какой-то модульный тест, который я считаю правильным, но он просто не работает. Может ли кто-нибудь дать мне представление о том, как я бы это сделал?
Это тест, который я придумал (неужели он так прост и легок?):
namespace TrainTest
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestTrainID()
{
Train train = new Train();
string id = "1S45";
train.TrainID = "1S45";
Assert.AreEqual(id, train.TrainID);
}
}
}
Не получается как? что такое сообщение об ошибке?
@ESuth Есть новости о статусе этой проблемы?





Вы должны проверить поведение и состояние изменений, вызванных поведением. У вашего класса нет поведения, и его состояние не меняется из-за поведения. Тестировать не на чем.
Допустимым тестом будет ситуация, когда в вашем классе будет конструктор, который устанавливает резервные поля, а затем утверждает, что свойства предоставляют значения из поддерживающих полей.
Тогда неудачные тесты укажут на ошибку в вашем конструкторе.
Итак, предполагая, что у вашего класса есть конструктор вроде (упрощен только для демонстрационных целей)
public class Train {
private string _trainID;
public Train(string id) {
_trainID = id;
}
//Get/Set for setting Train ID value.
public string TrainID {
get {
return _trainID;
}
set {
_trainID = value;
}
}
}
См. Приведенный ниже пример теста, который можно выполнить, чтобы убедиться, что конструктор ведет себя должным образом.
public class TrainUnitTest
{
[Fact]
public void Should_Get_TrainID()
{
//arrange
var expected = "1S45";
var subject = new Train("1S45");
//act
string actual = subject.TrainID;
//assert
Assert.Equal(expected, actual);
}
}
Да, @Nkosi, но во всех примерах не упоминается конструктор!
Это не проблема. Я обновил ваш пример, включив в него конструктор, чтобы OP лучше понимал, что вы объясняли.
Ура, я ценю это!
Вы зря тратите время на изобретение колеса.
Замените свои свойства на автоматически реализуемые свойства, и вдруг у вас не будет модульных тестов необходимость для ваших геттеров и сеттеров, потому что компилятор создает весь код геттера / сеттера и проверяет его правильность:
public class Train
{
public string TrainID { get; set; }
public string Departure { get; set; }
... etc. ...
}
(Поскольку вы упомянули, что это «игрушечный пример», предназначенный для начала работы с модульными тестами: да, предлагаемый вами тест подходит.)
Требование к модульному тесту не зависит от использования автоматизированных свойств или нет. Ваше утверждение ложно.
@Kris: Я не согласен: нет необходимости в модульном тестировании автоматических установщиков или получателей свойств. Разработчики Roslyn позаботились об этом модульным тестированием.
Я не об этом говорю. Я говорю, что нет необходимости тестировать класс, у которого нет изменений в поведении и / или состоянии. Вы говорите, что необходимость писать модульные тесты волшебным образом исчезает при использовании автоматически реализуемых свойств, что неверно.
@Kris: Я полностью согласен с этим. Однако я не понимаю, насколько это противоречит моему ответу. Исходное состояние кода имел изменяется: средство установки TrainID изменило это состояние поля члена _trainID.
С автоматически реализуемыми свойствами разницы нет. Их вспомогательные поля генерируются компилятором.
@Kris: Совершенно верно. Разница в том, что код для этого не написан вручную OP (а автоматически написан компилятором) и, следовательно, не нуждается в тестировании (если вы доверяете компилятору, что я бы сделал).
Я понимаю, что вы говорите, поверьте мне. Но это университетский проект, и нам сказали провести модульное тестирование этого конкретного класса. (который, как я знаю, кажется глупым, так как он тестировался без необходимости в любом случае)
У меня есть отдельный модульный тест, который проверяет фактические математические вычисления. Но единственный способ, который я вижу, - это проверить get / set. Просто создать строку с определенным значением, а затем создать объект поезда с таким же значением в требуемом свойстве и проверить, что два значения равны
@ESuth Ваш профессор специально говорил вам не использовать автоматически реализуемые свойства?
@Kris: Вы фактически отстаиваете необходимость модульного тестирования языковые особенности, что является явно абсурдным утверждением. Код не должен подвергать сомнению структуру (или язык), на которой он построен.
@Flater нет, я не такой.
@Esuth Если ваш профессор требует протестировать ваш геттер / сеттер, независимо от того, используются ли автоматически реализованные свойства или нет, то код, который вы написали и опубликовали, - это именно то, что вам нужно. Это так просто.
@Kris: Кроме того, если вы не собираетесь верить, что автоматические установщики работают, как задумано, как вы когда-нибудь собираетесь писать модульный тест, который не полагается на автоматические установщики? Потому что, если сеттер может ошибаться, может быть и геттер, а это значит, что вы никогда не сможете доверять автоматизированным свойствам, как бы тщательно вы их ни тестировали.
@Flater: В защиту Криса, я думаю, он скорее защищает тривиальные ручные геттеры / сеттеры в игрушечном примере OP не нужно тестировать. Я не подписываюсь на это в целом (это код, в котором мог бы неисправен, шаблонный код особенно, который может быть скопирован / вставлен), но я вижу, что соотношение затрат и выгод модульного тестирования такого кода не очень хорошее и Я бы, наверное, не стал тестировать его сам.
@Flater OP публикует класс, содержащий свойства с полями поддержки. ЕСЛИ существует конструктор, устанавливающий резервные поля, тогда да, правильно проверить, выставляют ли общедоступные свойства значения, установленные в поддерживающих полях.
@ESuth: Если это игрушечный пример, я думаю, что предложенный вами модульный тест в порядке. Однако я не понимаю, почему это не удается. Не могли бы вы добавить сообщение об ошибке к вашему вопросу?
@Flater: «Вы говорите, что необходимость писать модульные тесты волшебным образом исчезает при использовании автоматически реализуемых свойств, что неверно». Думаю, я понимаю, в чем заключается недоразумение. Я изменил свой ответ на * "... вдруг вам не нужны модульные тесты для ваших геттеров и сеттеров ...". Вы согласны сейчас?
Помимо семантики синтаксиса, если не было фактической ошибки в коде, который не показан, как вы упомянули, это пример игрушки или опечатка со значениями, переданными в тест, которая вызывает ошибку caparison, предоставленный тест должен пройти, как написано
В большинстве случаев структурирование потока тестирования может помочь избежать простых ошибок при организации и проведении тестов.
[TestClass]
public class TrainUnitTest
{
[TestMethod]
public void Should_Get_TrainID() {
//Arrange
string expected = "1S45";
Train subject = new Train();
subject.TrainID = expected;
//Act
string actual = subject.TrainID;
//Assert
Assert.AreEqual(expected, actual);
}
}
Вероятность вышеперечисленного сбоя теперь сужает проблему до тестируемого субъекта, виновного в этом.
В «реальном» приложении в этом нет необходимости - вы можете просто использовать автоматически реализованные свойства без модульного тестирования. Ваш профессор, вероятно, использует это как обучающее упражнение, чтобы вы привыкли к модульному тестированию, а также, вероятно, как возможность научить вас тому, что компилятор делает с автоматически реализуемыми свойствами. Если к следующему классу он / она не объяснил, что такое автоматически реализуемые свойства и что с ними делает компилятор, вы должны спросить. Как только вы и ваш класс поймете их, вам больше не нужно будет писать 100 строк кода вместо 10 строк.