首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ScalaMock和蛋糕模式-为什么我的存根没有被调用?

ScalaMock和蛋糕模式-为什么我的存根没有被调用?
EN

Stack Overflow用户
提问于 2017-07-12 14:01:08
回答 1查看 622关注 0票数 0

我有一个Scala应用程序,它使用Cake模式:

代码语言:javascript
运行
复制
trait RepositoryComponent {
  def repository: Repository

  trait Repository {
    def shouldSave(record: GenericRecord): Boolean
    def findRecord(keys: Array[String]): Long
    def insertRecord(record: GenericRecord)
    def updateRecord(keys: Array[String], record: GenericRecord)
    def cleanUp()
  }
}

trait DbRepositoryComponent extends RepositoryComponent with Logged {
  val connection: Connection
  val subscription: Subscription
  val schema: Schema

  def repository = new DbRepository(connection, subscription, schema)

  class DbRepository(connection: Connection, subscription: Subscription, schema: Schema) extends Repository {
    ...
  }

trait ConsumerComponent {
  def consumer: Consumer

  trait Consumer {
    def write(keys: Array[String], record: GenericRecord)
    def close()
  }
}

trait DbReplicatorComponent extends ConsumerComponent with Logged {
  this: RepositoryComponent =>

  def consumer = new DatabaseReplicator()

  class DatabaseReplicator extends Consumer {
    ...
  }

当我天真地开始测试consumer.write的实现时,我尝试了这样的方法(使用ScalaMock):

代码语言:javascript
运行
复制
class DbReplicatorComponentTests extends FunSuite with MockFactory {

  private val schema = new Schema.Parser().parse(getClass.getResourceAsStream("/AuditRecord.avsc"))
  private val record = new GenericRecordBuilder(schema)
    .set("id1", 123)
    .set("id2", "foo")
    .set("text", "blergh")
    .set("audit_fg", "I")
    .set("audit_ts", 1498770000L)
    .build()

  test("A record should be inserted if the audit flag is 'I' and no existing record is found") {
    val replicator = new DbReplicatorComponent with RepositoryComponent {
      override def repository: Repository = stub[Repository]
    }

    (replicator.repository.shouldSave _).when(record).returns(true)
    (replicator.repository.findRecord _).when(Array("123", "foo")).returns(0L)

    replicator.consumer.write(Array("123", "foo"), record)

    (replicator.repository.insertRecord _).verify(record)
  }
}

测试失败是因为我没有坚持实际的实现:

代码语言:javascript
运行
复制
Unsatisfied expectation:

Expected:
inAnyOrder {
  <stub-1> Repository.shouldSave({"id1": 123, "id2": "foo", "text": "blergh", "audit_fg": "I", "audit_ts": 1498770000}) any number of times (never called)
  <stub-2> Repository.findRecord([Ljava.lang.String;@4b8ee4de) any number of times (never called)
  <stub-4> Repository.insertRecord({"id1": 123, "id2": "foo", "text": "blergh", "audit_fg": "I", "audit_ts": 1498770000}) once (never called - UNSATISFIED)
}

Actual:
  <stub-3> Repository.shouldSave({"id1": 123, "id2": "foo", "text": "blergh", "audit_fg": "I", "audit_ts": 1498770000})
ScalaTestFailureLocation: com.generalmills.datalake.sql.DbReplicatorComponentTests at (DbReplicatorComponentTests.scala:12)
org.scalatest.exceptions.TestFailedException: Unsatisfied expectation:

这个问题突出了一个事实,那就是我真的不喜欢Scala。我不知道存根-3是从哪里来的。我在this question中成功地重新编写了我的测试,但是我希望在这里能有一些洞察力来帮助我更好地理解,为什么我没有在上面的测试中嘲笑我认为我是什么呢?

Fwiw,我是在C#背景下来到Scala的。

更新:根据下面的答案,这是可行的:

代码语言:javascript
运行
复制
test("A record should be inserted if the audit flag is 'I' and no existing record is found") {
    val replicator = new DbReplicatorComponent with RepositoryComponent {
      val _repo = stub[Repository]
      override def repository: Repository = {
        _repo
      }
    }

    (replicator.repository.shouldSave _).when(record).returns(true)
    (replicator.repository.findRecord _).when(Array("123", "foo")).returns(0L)

    replicator.consumer.write(Array("123", "foo"), record)

    (replicator.repository.insertRecord _).verify(record)
  }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-12 16:39:02

def repository: Repository --这是一种方法,每次调用它时都返回一个新存根。尝试将其设置为val,以在每次调用/访问时返回相同的存根:

代码语言:javascript
运行
复制
test("A record should be inserted if the audit flag is 'I' and no existing record is found") {
  val replicator = new DbReplicatorComponent with RepositoryComponent {
    override val repository: Repository = stub[Repository]
  }
  // ...
}

此外,您还使用Array作为参数类型。请注意scala中的Array("foo") != Array("foo"),因此我建议您在使用数组(findRecord)的when调用中使用argThat匹配器-参见此处:Unable to create stub with Array argument in ScalMock

或者尝试谓词匹配,如下所述:http://scalamock.org/user-guide/matching/

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45059866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档