Правильный способ проведения или выхода из модульного теста на основе значения в реальном времени - PullRequest
1 голос
/ 05 октября 2019

У меня есть класс, который проверяет, является ли текущий день недели средой. Это выглядит так:

public class Wednesday
{
    public string IsWednesday()
    {
        if (DateTime.Now.DayOfWeek == DayOfWeek.Wednesday)
        {
            return "It’s Wednesday";
        }
        else
        {
            return "It’s not Wednesday";
        }
    }
}

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

Я бы хотел охватить его модульными тестами для обоих случаев, когда текущий будний день - среда, а не среда.

Я новичокна модульное тестирование, и мне интересно, что будет лучшим решением в этом примере.

Сейчас я использую VS2019 с MS Test V2. Я протестировал оба сценария следующим образом:

[TestClass]
public class WednesdayTests
{
    [TestMethod]
    public void IsWednesday_CurrentWeekDayIsWednesday_ReturnsItsWedndesday()
    {
        if (!(DateTime.Now.DayOfWeek == DayOfWeek.Wednesday))
        {
            return; 
        }

        // Arrange
        Wednesday wednesdayObj = new Wednesday();

        // Act
        string result = wednesdayObj.IsWednesday();

        // Assert
        Assert.AreEqual("It’s Wednesday", result);
    }

    [TestMethod]
    public void IsWednesday_CurrentWeekDayIsNotWednesday_ReturnsItsNotWednesday()
    {
        if (!(DateTime.Now.DayOfWeek != DayOfWeek.Wednesday))
        {
            return;
        }

        Wednesday wednesdayObj = new Wednesday();

        string result = wednesdayObj.IsWednesday();

        Assert.AreEqual("It’s not Wednesday", result);
    }
}

Считается ли нормальным возвращение из метода тестирования, когда какое-то условие не выполняется, как в моем случае?

Или естьчто-то не так с моим решением?

Рад услышать любые предложения от опытных разработчиков программного обеспечения!

PS Просто заметил, что тест будет проводиться только в том случае, если это действительно среда :) Ничего себе, это точноэто не решение!

Ответы [ 2 ]

1 голос
/ 05 октября 2019

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

Один из способов сделать тестируемые модульными методы в зависимости от текущей даты - передать им постоянное значение «сейчас» (значение, предоставленное организатором теста).

    public string IsWednesday() => IsWednesday(DateTime.Now);

    public string IsWednesday(DateTime time)
    {
        if (time.DayOfWeek == DayOfWeek.Wednesday)
        {
            return "It’s Wednesday";
        }
        else
        {
            return "It’s not Wednesday";
        }
    }

Затем вы можете запустить тест с фиксированными датами, охватывающими оба случая: «среда» и «не среда». Этот подход является примером общей стратегии: все, что предоставляется средой во время нормального выполнения (имя машины, дата, культура и т. Д.), Должно быть параметром в тестируемом методе, а тестовый стенд должен обеспечивать диапазон значимых значений. .

Что касается реальных тестов (если позволите, сделайте себе одолжение и используйте NUnit или XUnit): они становятся тривиальными.

[TestMethod]
    public void ItsNotWednesday()
    {
        var wednesdayObj = new Wednesday();

        var result = wednesdayObj.IsWednesday(new DateTime(2019, 10, 5)); // Not a wednesday

        Assert.AreEqual("It’s not Wednesday", result);
    }
0 голосов
/ 05 октября 2019

Я бы сказал, что это плохо - иметь return; в модульных тестах.

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

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

На практике это означает, что вам нужно скрыть тот факт, что ваш производственный код зависит от DateTime.Now за абстракцией, которую вы можете контролировать в своем тестовом примере.

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