Объекты-компаньоны Scala часто предлагаются как объектные фабрики. Похоже, они хорошо работают в производственном коде, но как насчет вставки фиктивных объектов для тестирования? Сопутствующий объект не будет знать о фиктивном объекте и, следовательно, не сможет его создать.
Я бы хотел сделать что-то вроде этого:
class Foo {}
object Foo {
def create():Foo = new Foo()
}
class FooCreator(factory:Foo) {
def this() = this(Foo)
...
factory.create()
...
}
class FooMock extends Foo {}
object FooMock extends Foo {
def create():Foo = new FooMock()
}
// in a test
val fooCreator = new FooCreator(FooMock)
Это не будет работать, потому что объект-компаньон не может быть расширен. Я вынужден создать черту Factory для обоих сопутствующих объектов, которые будут смешаны:
trait FooFactory {
def create():Foo;
}
class Foo {}
object Foo extends FooFactory {
def create():Foo = new Foo()
}
class FooCreator(factory:FooFactory) {
def this() = this(Foo)
...
factory.create()
...
}
class FooMock extends Foo {}
object FooMock extends FooFactory {
def create():Foo = new FooMock()
}
// in a test
val fooCreator = new FooCreator(FooMock)
Есть ли лучший способ сделать это? Создание фабричной черты просто кажется неправильным, так как это то, что объект-компаньон должен быть хорош в. (Имейте в виду, что артефакты Mock известны только подсистеме тестирования, поэтому я не могу решить эту проблему, позволив объекту Foo создать экземпляр FooMock - общий шаблон в рабочем коде).