Как создать экземпляр модульного теста?
У меня есть Carpenter
класс, который делает это, используя работу Lathe
и Wood
объект.
class Carpenter
{
function Work()
{
$tool = new Lathe();
$material = new Wood();
$tool->Apply($material);
}
}
Lathe
зависит от интерфейса под названием Material
так что я могу легко юнит тест Lathe
давая ему подделку Material
в моем модульном тесте. Wood
не зависит ни от чего, поэтому его также можно легко проверить.
interface Material {
// Various methods...
}
interface Tool {
function Apply(Material $m);
}
class Wood implements Material {
// Implementations of Material methods
}
class Lathe {
function Apply(Material $m) {
// Do processing
}
}
Тем не мение, Carpenter
зависит от конкретных классов Lathe
а также Wood
потому что он должен создавать их экземпляры. Это означает, что в настоящее время я не могу Work()
метод без случайного привлечения Lathe
а также Wood
под тестом.
Как я должен изменить свой дизайн на модульное тестирование Carpenter
?
2 ответа
Здесь вы можете выбрать несколько направлений:
- Используйте Constructor Injection и просто введите инструмент и материалы в плотник.
- Если внедрение экземпляров по какой-либо причине не работает (возможно, из-за того, что вам нужно создавать новые экземпляры для каждого вызова метода Work), вы можете вместо этого ввести абстрактные фабрики.
- Вы также можете использовать подход Factory Method, описанный ctford, но он требует от вас также создавать специфичные для теста переопределения, чтобы иметь возможность выполнять модульное тестирование, и хотя это совершенно допустимая вещь, это просто больше работы, а во многих случаях другие альтернативы лучше и гибче.
Ключ должен отделить создание объекта от использования объекта в Carpenter
,
class Carpenter
{
function getTool() {
return new Lathe();
}
function getMaterial() {
return new Wood();
}
function Work()
{
$tool = getTool();
$material = getMaterial();
$tool->Apply($material);
}
}
Таким образом, вы можете переопределить getTool()
а также getMaterial()
методы в TestCarpenter
класс и ввести свой собственный Material
а также Tool
подделки.
getTool()
а также getMaterial()
Методы также могут быть проверены отдельно.
Майкл Перья назовет getTool()
а также getMaterial()
Методы "швы", потому что они являются точками, где подделки могут быть вставлены без изменения окружающего кода.