Как протестировать логику, которая зависит от текущей даты

У меня есть этот метод, который зависит от текущей даты. Это проверяет, ли сегодня Sun, понедельник, вторник или в среду, то это дает 5 дней времени выполнения заказа для прибытия поставленных объектов. Если ее Thur, пятница или Находился тогда, это дает 6 дней времени выполнения заказа для учета в течение выходных.

private DateTime GetEstimatedArrivalDate()
{
    DateTime estimatedDate; 
    if (DateTime.Now.DayOfWeek >= DayOfWeek.Thursday)
    {
        estimatedDate = DateTime.Now.Date.AddDays(6);
    }
    else
    {
        estimatedDate = DateTime.Now.Date.AddDays(5);
    }
    return estimatedDate; 
}

Фактическая логика оценки более сложна. Я упростил его в целях этого вопроса. Мой вопрос состоит в том, как я пишу модульный тест на что-то вроде этого, что зависит от сегодняшней даты?

8
задан Rohit Agarwal 17 February 2010 в 20:49
поделиться

8 ответов

Вам нужно передать текущую дату в качестве параметра:

private DateTime GetEstimatedArrivalDate(DateTime currentDate)
{
    DateTime estimatedDate; 
    if (currentDate.DayOfWeek >= DayOfWeek.Thursday)
    {
        estimatedDate = currentDate.AddDays(6);
    }
    else
    {
        estimatedDate = currentDate.AddDays(5);
    }
    return estimatedDate; 
}

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

DateTime estimatedDate = GetEstimatedArrivalDate(DateTime.Now.Date);

Затем вы можете протестировать его следующим образом:

DateTime actual = GetEstimatedArrivalDate(new DateTime(2010, 2, 10));
DateTime expected = ...;
// etc...

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

19
ответ дан 5 December 2019 в 05:03
поделиться

Нет, вы должны заметить, что объединение двух будет результатом в видимых побег, отображаемых в данных.

-121--1668951-

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

http://spikes.codeplex.com/releases/view/40655


WebAdmin - это просто встроенное приложение ASP.NetWebAdministrationFiles, очищенное кодовыми кодами, чтобы сделать возможной настройку и рефакторинг.

Это предвестник более комплексного asp.net приложения веб-администрирования, которое будет складываться в множество проблем конфигурации, которые появились за последние 5 лет и версии 3 .net.

Использование: Указать WebAdmin на сайте, указав, если это необходимо, «» startPhysicalPath «» и, если это уместно, «» (виртуальный путь) например. default.aspx? applicationPhysicalPath=C:\Projects\WebAdmin\WebApplication1\&applicationUrl = /

лучше, если идентичность, запускающая это приложение, подняла разрешения. Таким образом, имеет смысл запустить его с сервера webdev или кассини. Если вы планируете поместить его в IIS, помните, что используется олицетворение, и настройте vdir соответствующим образом.

Известные проблемы:

Еще предстоит отследить все возможные случаи исключения «Invalid postback». Это вызвано тем, что через некоторое время после того, как встроенные файлы веб-администратора были написаны и не были обновлены, было закрыто отверстие безопасности.

Найдя эту страницу, перейдите на эту страницу и поместите ее в директиву страницы EnureEventValidation = «false» и разместите на вкладке http://spikes.codeplex.com Проблемы.

-121--2279428-

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

public interface IDateTimeProvider
{
    DateTime Now { get; }
}

Реальная услуга будет:

public class DateTimeProvider: IDateTimeProvider
{
    public DateTime Now
    {
        get
        {
            return DateTime.Now;
        }
    }
}

И тестовая услуга будет:

public class TestDateTimeProvider: IDateTimeProvider
{
    private DateTime timeToProvide;
    public TestDateTimeProvider(DateTime timeToProvide)
    {
        this.timeToProvide = timeToProvide;
    }

    public DateTime Now
    {
        get
        {
            return timeToProvide;
        }
    }
}

Для служб, которые требуют текущего времени, пусть они принимают IDateTimeProvider в качестве зависимости. Для реальной вещи передайте новый DateTimeProvider (); Когда вы являетесь компонентом, передайте новый EventDateTimeProvider (timeToStartFor).

10
ответ дан 5 December 2019 в 05:03
поделиться

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

Еще один интересный способ - немного изменить вашу реализацию на:

private DateTime GetEstimatedArrivalDate()
{
    return GetEstimatedArrivalDate(DateTime.Now);
}

private DateTime GetEstimatedArrivalDate(DateTime forDate)
{
    DateTime estimatedDate; 
    if (forDate.DayOfWeek >= DayOfWeek.Thursday)
    {
        estimatedDate = forDate.Date.AddDays(6);
    }
    else
    {
        estimatedDate = forDate.Date.AddDays(5);
    }
    return estimatedDate; 
}

А затем использовать метод с параметром для проверки на «немедленных» датах.

1
ответ дан 5 December 2019 в 05:03
поделиться

Заставьте ваш класс принимать параметр IClock (через конструктор или свойство)

interface IClock
{
    DateTime Now { get; }
}

Затем вы можете использовать поддельную реализацию для тестирования

class FakeClock : IClock
{
    DateTime Now { get; set }
}

, а в остальное время - реальная реализация.

class SystemClock : IClock
{
    DateTime Now { get { return DateTime.Now; } }
}
3
ответ дан 5 December 2019 в 05:03
поделиться

PushButityEngine предоставляет многообещающую игровую рамку.

Если вы ищете 2D игры Flashpunk является довольно новым, стоит посмотреть, я не тестировал все это.

-121--2393397-

http://silverlight.net имеет кучу коротких видео «как мне». Следите за ними с открытыми VS2008 и подыгрывайте. Книга в порядке, но Silverlight 4 за углом.

-121--3266082-

Кажется, что существует ограниченное количество случаев, которые можно проверить каждый явно. Метод зависит от сегодняшней даты, но выход зависит только от дня недели, и каждая дата имеет день недели.

0
ответ дан 5 December 2019 в 05:03
поделиться

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

0
ответ дан 5 December 2019 в 05:03
поделиться

Я бы предложил сделать так, как предлагает Марк, но с добавлением перегруженного вызова для производственного использования, который не принимает никаких параметров и использует DateTime.Now

private DateTime GetEstimatedArrivalDate()
{
    return GetEstimatedArrivalDate(DateTime.Now);
}

private DateTime GetEstimatedArrivalDate(DateTime currentDate)
{
    DateTime estimatedDate; 
    if (currentDate.DayOfWeek >= DayOfWeek.Thursday)
    {
        estimatedDate = currentDate.AddDays(6);
    }
    else
    {
        estimatedDate = currentDate.AddDays(5);
    }
    return estimatedDate; 
}
1
ответ дан 5 December 2019 в 05:03
поделиться

Я дам спорный ответ, не тестируйте Это.

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

1
ответ дан 5 December 2019 в 05:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: