2011-11-27 39 views
2

Scala伴侣对象经常被建议作为对象工厂。他们似乎在生产代码中很好地工作,但插入模拟对象以进行测试呢?伴随对象不会知道模拟对象,因此不能实例化它。通过扩展工厂特征将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) 

这不会起作用,因为同伴对象不能被延长。我不得不创建一个工厂的特质对两个同伴反对混入:

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) 

有没有更好的方式来做到这一点?创建工厂特质只是感觉不对,因为这是伴侣对象应该擅长的。 (请记住,模拟构件只对测试子系统是已知的,所以我不能通过让对象Foo创建一个FooMock实例 - 生产代码中的常见模式)来解决问题。

+0

我认为,你需要的是**依赖注入**框架/库/方法 – tenshi

回答

1

你可能想看看ScalaMock,嘲弄的框架斯卡拉可以(除其他事项外)模拟对象创建(编译器调用)。这正是它打算解决的问题之一。