Scala:模拟伴随对象和模型与服务方法

2024-01-22

我看到了多个关于如何模拟伴随对象的问题,经常提到的答案是使用 scalamock,但根据doc http://scalamock.org对于版本 3,模拟伴生对象仍标记为将来使用。

那么模拟伴生对象的方法是什么呢?如果没有,是否有比我已经启用测试更好的方法来做事情?

使用play框架的代码:

Model

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)
      ......
   }
}

我如何嘲笑Article.get(id)?

在我让它工作之前,我以不同的方式构建了代码:

工作测试方法

Model

case class Article(id: String, preview: String)

Service

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. 是否有一种“正确”的方法来构建代码?如果有,为什么?

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)
      ......
   }
}

当测试文章资源时,您可以创建一个您选择的函数 String => Article 。你甚至不需要一个框架:)

编辑:您甚至可以使用伴随对象的方法作为默认值,以便更轻松地在生产代码中实例化。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala:模拟伴随对象和模型与服务方法 的相关文章

随机推荐