Модульное тестирование дельты времени - PullRequest
1 голос
/ 15 сентября 2011

У меня есть следующий метод, который я хотел бы для модульного тестирования:

public void Upload(string identifier, Stream data)
{
    var startTime = SystemTime.Now;

    innerDataIntegrationInterface.Upload(identifier, data);

    var endTime = SystemTime.Now;

    TimeSpan totalUploadTime = endTime.Subtract(startTime);
    float transferRate = data.Length / (float)(totalUploadTime.Seconds + totalUploadTime.Milliseconds);

    m_log.Info(string.Format("Total uploading time for '{0}' was {1:00}.{2:000000} milliseconds transfered at {3} bytes/sec", identifier, totalUploadTime.Seconds, totalUploadTime.Milliseconds, transferRate));
}

По сути, я уже внедряю объект SystemTime, чтобы настроить его в своем тесте, но не могу понять, что делать, чтобы переменные startTime и endTime получали разные значения, поэтому я могу утверждать, что метод m_log.Info вызывается с правильными значениями для переменных totalUploadTime и TransferRate.

Любые идеи будут оценены.

Ответы [ 4 ]

4 голосов
/ 15 сентября 2011

Идея часов - что-то может получить текущее время - по сути является услугой , от которой вы зависите. Если вы зависите от него явно через какой-либо интерфейс (IClock), как и любой другой сервис. Затем вы можете создать «производственную» реализацию, которая делегирует System.DateTime.UtcNow или System.DateTime.Now и поддельную реализацию или макет для тестирования.

Лично по моему опыту, стоит иметь подделку, которую вы можете установить, продвигать и т. Д., А не использовать фальшивую среду для этого конкретного сценария - это техника, которую я видел и использовал сам довольно часто (именно поэтому Noda Time поддерживает это с интерфейсом IClock и реализацией StubClock.

1 голос
/ 15 сентября 2011

Если innerDataIntegrationInterface.Upload является частью смоделированного интерфейса, вы можете смоделировать метод Upload, например:

var mock = new Mock<innerDataIntegrationInterface>();
mock.Setup(m => m.Upload(identifier, data)).Callback<object>(
    c =>
         {
          //increment SystemTime.Now
          //or call
          //Thread.Sleep(1); to sleep for microsecond
         });

Выше приведено в c # с использованием Moq

1 голос
/ 15 сентября 2011

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

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

(он же «Собери, затем используй» из Образцы, устраняющие насмешки .)

1 голос
/ 15 сентября 2011

Можете ли вы заставить свой объект Mock SystemTime увеличивать его значение в Now Getter?Это сделало бы их разными.

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