Как провести модульное тестирование частного кода без рефакторинга для разделения класса?

Предположим, у меня есть частная процедура, которая выполняет некоторые вычисления:

private function TCar.Speed: float
{
   Result = m_furlogs * 23;
}

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

public function TCar.Speed: float
{
   Result = CalculateSpeed(m_furlogs);
}

private function TCar.CalculateSpeed(single furlogs): float 
{
   Result = furlogs * 23;
}

Теперь я могу выполнять все виды тестов на CalculateSpeed ​​:

Check( CalculateSpeed(0)  =  0);
Check( CalculateSpeed(1)  = 23);
Check( CalculateSpeed(2)  = 46);
Check( CalculateSpeed(88) = -1);

За исключением того, что я не могу выполнить эти тесты, потому что CalculateSpeed ​​ является частным для TCar . Абстрактный принцип модульного тестирования заключается в том, что вы никогда не тестируете частный код - только общедоступные интерфейсы. На практике * x * Unit обычно не структурирован так, чтобы иметь возможность доступа к частным методам отдельного тестируемого класса.

Проблема в том, что ни один из остальных классов не настроен для обработки модульных тестов. Это первая процедура, в которой будет проводиться какое-либо тестирование. И очень сложно настроить для класса хоста набор начальных условий, которые позволят мне тестировать вызов CalculateSpeed ​​ с каждым набором входных данных, который мне нужен.

Единственная альтернатива, которую я вижу, - это перенос этого частного вычисления в его собственный TCarCalculateSpeed ​​ класс:

public class TCarCalculateSpeed
{  
   public function CalculateSpeed(float furlogs)
   {
      Result = furlogs * 23;
   }
}

Целый класс, предназначенный для раскрытия одного метода, который должен быть частным, просто чтобы я мог его протестировать?

Взрыв класса.

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

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

В настоящее время я думаю, что лучше всего добавить метод Test в мой класс Car и просто назвать его:

TCar Car = new TCar();
Car.RunTests;

public procedure TCar.RunTests
{
   Check( CalculateSpeed(0)  =  0);
   Check( CalculateSpeed(1)  = 23);
   Check( CalculateSpeed(2)  = 46);
   Check( CalculateSpeed(88) = -1);
}

Но теперь мне нужно выяснить, как заставить TCar.RunTests запускаться внешним TestRunner , который предназначен только для использования классов TestCase .

Примечание. : Я изо всех сил пробовал смешивать синтаксис из множества языков. Другими словами: языковой агностик.

5
задан Ian Boyd 29 September 2010 в 19:05
поделиться