我看到了关于如何模拟伴随对象的多个问题,经常提到的答案是使用scalamock,但根据版本3的文档,模拟伴随对象仍然标记为将来。
那么,如何模拟同伴对象呢?如果没有,还有比我已经拥有的启用测试更好的方法吗?
使用play框架的代码:
模型
case class Article(id: String, preview: String)
object Article {
def get(id: String) = {
......
}
}
文章资源
class ArticleResource extends Controller {
def getArticle(id: String) = authenticate {
......
Article.get(id)
......
}
}
如何模仿< code>Article.get(id)?
在我让它工作之前,我的代码结构不同:
工作测试方法
模型
case class Article(id: String, preview: String)
服务
class ArticleService {
def get(id: String) = {
......
}
}
object ArticleService {
def apply = new ArticleService
}
文章资源
class ArticleResource(articleService: ArticleService) {
def getArticle(id: String) = authenticate {
......
articleService.get(id)
......
}
}
object ArticleResource extends controllers.ArticleResource(ArticleService())
在测试中,我将mock[ArticleService]
注入到资源中进行测试。
我一直听说前一种方法(模型)是“正确”的方法,我一直不明白为什么,所以我尝试了它并在测试中遇到了问题,但我仍然不明白为什么它是更好的方法。(考虑到测试的困难,我现在实际上对后一种方法感觉更强烈)
所以我有两个问题:
1) 我认为这是不可能的,我也不认为这是个好主意。我认为将需要模仿的行为放在伴随对象中是不可取的。
2) 我也认为你的第一种方法更好。如果您希望将当前代码保持在最小的更改范围内,那么:
case class Article(id: String, preview: String)
object Article {
def get(id: String) = {
......
}
}
class ArticleResource(articleFinder: (String) => Article = Article.get) {
def getArticle(id: String) = authenticate {
......
articleFinder(id)
......
}
}
在测试ArticleResource时,你可以创建一个函数String =
编辑:您甚至可以使用伴随对象的方法作为默认值,以便更容易在生产代码中实例化。