我应该模拟Trait还是使用Scala Mock模拟类

我应该模拟Trait还是使用Scala Mock模拟类,scala,scalamock,Scala,Scalamock,假设我有以下几点: @ImplementedBy(classOf[DefaultFoo]) 特色食品{ 定义a(s:字符串):Int } 类DefaultFoo@Inject()()扩展了Foo{ 覆盖定义a(s:字符串)=1 } @实现者(classOf[DefaultBaz]) 性状Baz{ def b(s:字符串):整数 } 类DefaultBaz@Inject()(val f:Foo)扩展了Baz{ 覆盖定义a(s:字符串)=1 } 如果我想测试,比如说DefaultBaz,我通常使用

假设我有以下几点:

@ImplementedBy(classOf[DefaultFoo])
特色食品{
定义a(s:字符串):Int
}
类DefaultFoo@Inject()()扩展了Foo{
覆盖定义a(s:字符串)=1
}
@实现者(classOf[DefaultBaz])
性状Baz{
def b(s:字符串):整数
}
类DefaultBaz@Inject()(val f:Foo)扩展了Baz{
覆盖定义a(s:字符串)=1
}
如果我想测试,比如说DefaultBaz,我通常使用ScalaMock,我会在我的测试规范中模拟如下:

class DefaultBazSpec使用MockFactory扩展了AnyWordSpec{
val mockFoo=mock[Foo]
val b=新的DefaultBaz(mockFoo)
//写测试
}
但我也可以这样做:

val mockFoo=mock[DefaultFoo]

哪一个更好?模拟trait或默认类实现?

最好两者都不使用。通常应避免模拟(特别是在Scala中)

但是,即使您决定继续进行模拟,模拟被测试的类也会破坏测试的全部目的:被测试的代码与生产代码没有任何共同之处


mock用于模拟受测类的依赖项(例如构造函数参数或方法参数)。

最好两者都不使用。通常应避免模拟(特别是在Scala中)

但是,即使您决定继续进行模拟,模拟被测试的类也会破坏测试的全部目的:被测试的代码与生产代码没有任何共同之处


mock用于模拟受测类的依赖项(例如构造函数参数或方法参数)。

为什么不使用一个简单的类来扩展trait,它可以完成模拟所要做的事情,但没有反射和奇特的语法。我没有给出一个好的例子。我想描述一个场景,
Foo
被注入到另一个类中。该类的测试将使用Scalamock模拟版本的
Foo
。现在我可以做
mock[Foo]
mock[DefaultFoo]
。我想知道这样做的利弊,我认为您的代码片段中有一些错误,您可能希望
DefaultBaz
扩展
Baz
,并接收
Foo
的实例作为参数。-无论如何,我知道您已经习惯于用java的方式来处理反射,以解决(复杂化)每个琐碎的问题,比如传递依赖项和测试。但是,Scala中的许多人更喜欢保持简单,只需手动传递依赖项,并使用简单的存根进行测试,而不是模拟。是的,很抱歉,我修复了这个问题,并显示我正在使用Guice DI框架。我知道FP方法说不要使用DI,但我使用的是Play Framework,它随Guice DI一起提供,所以我使用它,这就是为什么我采用这种方式进行测试,主要是因为您的
DefaultBaz
应该适用于任何
Foo
,并且因为模仿
DefaultFoo
可能比普通界面更难(顺便说一句,不需要嘲笑,但你一定厌倦了我一遍又一遍地重复)。为什么不使用一个简单的类来扩展trait呢?这个类与mock类似,但没有反射和奇特的语法。我没有给出一个好的例子。我想描述一个场景,其中
Foo
被注入到另一个类中。该类的测试将使用一个使用Scalamock的模拟版本的
Foo
。现在我可以了执行
mock[Foo]
mock[DefaultFoo]
。我想知道这样做的利弊,我认为您的代码片段中有一些错误,您可能希望
DefaultBaz
扩展
Baz
,并接收
Foo
的一个实例作为参数。-无论如何,我知道您已经习惯了用java方式处理需要解决的反射问题(复杂)每个琐碎的问题,比如传递依赖项和测试。但是,Scala中的许多人更喜欢保持简单,只需手动传递依赖项,并使用简单的存根进行测试,而不是模拟。是的,很抱歉,我修复了这个问题,并表明我正在使用Guice DI框架。我知道FP方法说不要使用DI,但我使用的是Play框架a它与Guice DI一起提供,所以我使用它,这就是为什么我用这种方式进行测试,主要是因为你的
DefaultBaz
应该适用于任何
Foo
,也因为模仿
DefaultFoo
可能比普通界面更难(顺便说一句,它不需要模仿,但你一定厌倦了我一遍又一遍地重复它)。我使用mock的方法是在上面的示例中模拟类中方法的行为。例如,我有另一个类注入了
Foo
。然后在我对另一个类的测试中,我只需执行
val f=mock[Foo]
然后为方法
a
的行为编写模拟,以便可以用来测试另一个类。请参阅我的最新帖子。它更好地描述了场景。模拟
Foo
是一个较小的邪恶。模拟DefaultFoo的邪恶是什么?这是我的主要问题@simajdot我使用模拟的方式是模拟m的行为上面例子中的类中的方法。比如说,我有另一个类注入了
Foo
。然后在我对另一个类的测试中,我只做
val f=mock[Foo]
然后为方法
a
的行为编写模拟,这样它们就可以用来测试另一个类。请参阅我的更新帖子。它更好地描述了场景。模拟
Foo
是一个较小的邪恶。模拟DefaultFoo的邪恶是什么?这是我的主要问题@simajdo