Код поблочного тестирования, который действительно датирует обработку на основе сегодняшней даты

Я использую C ++, но могу ответить на ваш вопрос. Алгоритм в порядке , но вы должны перефразировать ваш вопрос, чтобы отразить, что у вас возникли проблемы с пониманием алгоритма .

1) Почему мы создаем вложенный класс?
Чтобы избежать конфликта типов

+- IntersectionOfTwoSets (class) ------+
|    |                                 |
|    o- Point (class)                  |
|    |                                 |
|    o- intersectionOf (function)      |
|                                      |
+--------------------------------------+

можно реализовать без IntersectionOfTwoSets, но обратите внимание, что [116 ] - очень распространенное имя, и, возможно, оно уже реализовано в любой библиотеке, которую вы собираетесь добавить в свой проект. реализация Point в IntersectionOfTwoSets делает вашу реализацию уникальной (концепция, известная как namespace в C ++ и использование которой считается хорошей практикой программирования)


стандарт [1122 ] для цикла синтаксис: for ( init ; condition ; increment ])

Заметьте, что отсутствует компонент приращения цикла, вместо этого вы найдете его в цикле


2) [ 1127] Как i ++ и j ++ реализованы в методе intersectionOf?
i++ - это просто i += 1;

- это упрощенная версия кода

given two sets a & b
sort a & b
initialize empty array (result)
loop (...)
| if (a[i] == b[j])
|  add a[i] to result, then increment i & j
| if (a[i] < b[j])
|  increment i
| if (b[j] < a[i])
|  increment j
| if (i >= a.size()) or (j >= b.size())
|  stop
return result

давайте проверим алгоритм на множестве целых чисел

let a: [2, 1, 10, 9]
let b: [1, 5, 2, 7, 6]

let result: []

Arrays.sort(a); // a: [1, 2, 9, 10]
Arrays.sort(b); // b: [1, 2, 5, 6, 7]

loop(...)
| 1: add 1 to result, increment i & j
| 2: add 2 to result, increment i & j
| 3: (j == 2) increment only j (5 < 9)
| 4: (j == 3) increment only j (6 < 9)
| 5: (j == 4) increment only j (7 < 9)
| 6: (j == 5) stop because j >= b.size()

return result // [1, 2]

, он также должен работать на множестве точек

] 3) Как основной метод будет создавать объекты из двухточечного массива?
в C ++ синтаксис:

IntersectionOfTwoSets::Point a[n], b[n];
or
List<IntersectionOfTwoSets::Point> a, b;

, но в Java Я почти уверен, что это:

List<IntersectionOfTwoSets.Point> a, b;
or
IntersectionOfTwoSets::Point a = new IntersectionOfTwoSets::Point[n];
IntersectionOfTwoSets::Point b = new IntersectionOfTwoSets::Point[n];
15
задан Richard Everett 6 August 2017 в 01:09
поделиться

8 ответов

В нашем коде мы всегда вытаскиваем использование текущей даты DateTime. Теперь (.NET, в нашем случае). Как может Вы модульный тест такой код?

Это - зависимость и недетерминированная зависимость в этом. Необходимо разделить ответственность кода немного больше.

Прежде:

  • существует некоторый код, который использует текущую дату и время, чтобы сделать X.

После:

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

, Эти два набора кода не должны зависеть друг от друга.

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

16
ответ дан 1 December 2019 в 00:08
поделиться

Используя DI для введения "Текущей даты & Время" является, конечно, излишеством. Я осуществил бы рефакторинг код для работы на произвольную дату. Таким образом, я изменился бы function calculateRevenue() на function calculateRevenueOn(datetime date). Это намного легче протестировать и использовать в случае, если Вам нужно вычисление для некоторых дат кроме тока.

12
ответ дан 1 December 2019 в 00:08
поделиться

Вы могли сделать mockobject, который моделирует DateTime. Теперь

вот статья с примером где DateTime. Теперь дразнится: http://geekswithblogs.net/AzamSharp/archive/2008/04/27/121695.aspx

3
ответ дан 1 December 2019 в 00:08
поделиться

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

Затем в Вашем производственном коде можно назвать их и дать им текущую дату как параметр и все еще протестировать пограничные случаи к содержанию основы в модульных тестах.

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

9
ответ дан 1 December 2019 в 00:08
поделиться

Я использовал очень прагматический подход, обсужденный Oren Eini (иначе Ayende Rahien) в его blogspots , Имеющем дело со временем в тестах .

существует статический класс как это:

public static class SystemTime
{
    public static Func<DateTime> Now = () => DateTime.Now;
}

Вы - код, становится:

Entity.LastChange = SystemTime.Now();

И Ваш тест стал бы:

SystemTime.Now = () => new DateTime(2000,1,1);
repository.ResetFailures(failedMsgs); 
SystemTime.Now = () => new DateTime(2000,1,2);
var msgs = repository.GetAllReadyMessages(); 
Assert.AreEqual(2, msgs.Length);
10
ответ дан 1 December 2019 в 00:08
поделиться
public interface ITimeProvider {
    DateTime Now { get; }
}

public class SystemTimeProvider : ITimeProvider {
    public virtual DateTime Now { get { return DateTime.Now; } }
}

public class MockTimeProvider : ITimeProvider {
    public virtual DateTime Now { get; set; }
}

public class ServiceThatDependsOnTime {
    protected virtual ITimeProvider { get; set; }
    public ServiceThatDependsOnTime(ITimeProvider timeProvider) {
        TimeProvider = timeProvider;
    }
    public virtual void DoSomeTimeDependentOperation() {
        var now = TimeProvider.Now;
        //use 'now' in some complex processing.
    }
}

[Test]
public virtual void TestTheService() {
    var time = new MockTimeProvider();
    time.Now = DateTime.Now.AddDays(-500);
    var service = new ServiceThatDependsOnTime(time);
    service.DoSomeTimeDependentOperation();
    //check that the service did it right.
}
2
ответ дан 1 December 2019 в 00:08
поделиться

Вы уже дали ответ. Можно записать маленький класс обертки вокруг функций даты и времени, которые можно затем ввести в классах, которые должны получить текущую дату. Замена DateTime. Теперь с вызовом к Вашему интерфейсному объекту.

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

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

3
ответ дан 1 December 2019 в 00:08
поделиться

Внедрение зависимости может быть решением для этого, да.

то, Что Вы сделаете, создают, например, интерфейс IDateTimeProvider с методом: GetDate (). В Вашем классе производственного кода Вы реализуете, возвращают DateTime. Теперь.

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

0
ответ дан 1 December 2019 в 00:08
поделиться
Другие вопросы по тегам:

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