Reputation: 61
Im running into an issue with scala mock. Where the error message indicates that it cannot log a call to a mock object.
I've set up the following spec. I've a few mocks setup but nothing to extraordinary:
"get accounts" in {
import CodatAccount._
val mockCompanyId = UUID.randomUUID().toString
val mockLedger = Ledger.defaultInstance.copy(connection =
Ledger.Connection.CodatConnection(common.CodatConnection(codatCompanyUuid = mockCompanyId)),
ledgerUuid = UUID.randomUUID().toString
)
def getMockAccount = CodatAccount(
id = Some(UUID.randomUUID().toString),
`type` = CodatAccountType.Asset,
status = CodatStatus.Active,
isBankAccount = false)
val mockAccounts =
CodatAccountsPage(Seq(getMockAccount, getMockAccount, getMockAccount, getMockAccount, getMockAccount))
val expectedAccountsJson = mockAccounts.results.asJson
val mockGleanAccounts = mockAccounts.results.map(_.asProto(mockLedger))
(mockAccountCacheDAO.refreshCache(_: Seq[Account], _: UUID, _: UUID)(_: ExecutionContext))
.expects(mockGleanAccounts.toSeq, UUID.fromString(mockLedger.ledgerUuid), *, *)
.returns(Future.successful())
(mockSyncDataLakeDAO.getSyncDataByLedgerIdAndDataType(_: UUID, _: DataTypeEntity)(_: ExecutionContext))
.expects(UUID.fromString(mockLedger.ledgerUuid), DataTypeEntity.ACCOUNT, *)
.returns(Future.successful(None))
(mockSyncDataLakeDAO.upsertSyncDataLake(_: SyncData)(_: ExecutionContext))
.expects(where { (syncData: SyncData, _) =>
syncData.ledgerId == UUID.fromString(mockLedger.ledgerUuid) && syncData.json == expectedAccountsJson
})
.returns(Future.successful())
(mockHttpClient
.get[CodatAccountsPage](_: Uri, _: Map[String, String])(_: Decoder[CodatAccountsPage]))
.expects(
uri"/companies/${mockCompanyId}/data/accounts".addParam("query", "status=Active").addParam("page", "1"),
Map[String, String](),
*)
.returns(Right(mockAccounts).future)
(mockHttpClient
.get[CodatAccountsPage](_: Uri, _: Map[String, String])(_: Decoder[CodatAccountsPage]))
.expects(
uri"/companies/${mockCompanyId}/data/accounts".addParam("query", "status=Active").addParam("page", "2"),
Map[String, String](),
*)
.returns(Right(CodatAccountsPage(Nil)).future)
codatLedgerService.getAccounts(mockLedger, None).map {
case Nil => fail("failed get accounts")
case accounts =>
accounts shouldBe mockAccounts.results.map(_.asProto(mockLedger))
}
}
And have the following application code under test:
override def getAccounts(ledger: states.Ledger, modifiedAfter: Option[Instant]): Future[Iterable[common.Account]] = {
val ledgerId = UUID.fromString(ledger.ledgerUuid)
val codatAccounts = ListBuffer.empty[CodatAccount]
ledger.extractAndMap(entity = "accounts") { (companyId, entity) =>
log.info(s"Codat getAccounts for companyId= [$companyId]")
val path = uri"/companies/${companyId}/data/accounts".addCommonParams(modifiedAfter)
def request(pageNumber: Int) = {
httpClient.get[CodatAccountsPage](path = path.addParam("page", pageNumber.toString)).collect {
case Right(responsePage) =>
codatAccounts.addAll(responsePage.results)
Right(responsePage.results.map(_.asProto(ledger)))
}
}
val resultF = UnfoldIO
.getWhileNotEmpty(request = request, pageNumber = 1)
.collectAndRecover(entity = entity, companyId = companyId)
resultF.map { accounts =>
updateAccountsCache(ledgerId = ledgerId, accounts = accounts.toSeq, codatAccounts = codatAccounts.toSeq)
}
resultF.recoverWith { case _: Timeout =>
accountCacheDAO.getAccounts(ledgerId = ledgerId)
}
}
}
private def updateAccountsCache(
ledgerId: UUID,
accounts: Seq[Account],
codatAccounts: Seq[CodatAccount]): Future[Unit] = {
val syncData = SyncData(ledgerId = ledgerId, dataType = DataTypeEntity.ACCOUNT, codatAccounts.asJson)
val resultF = for {
existingSyncDataO <- syncDataLakeDAO.getSyncDataByLedgerIdAndDataType(
ledgerId = ledgerId,
dataType = DataTypeEntity.ACCOUNT)
updateCache = existingSyncDataO.forall(existingSyncData => !existingSyncData.compareHashes(compareTo = syncData))
if updateCache
_ <- syncDataLakeDAO.upsertSyncDataLake(syncData = syncData)
result <- accountCacheDAO.refreshCache(accounts = accounts, ledgerId = ledgerId, syncDataId = syncData.syncDataId)
} yield result
resultF.onComplete {
case Failure(ex) => log.error(f"Failed to update the account cache due to ${ex.getMessage}", ex)
case Success(_) => log.debug("Successfully updated the account cache")
}
resultF
}
The issue is that Im getting the following exception when I try to run my test:
2022-06-29 00:35:15,870 ERROR com.gleanhq.ledger.external.CodatLedgerServiceImpl - Failed to update the account cache due to Can't log call to mock object, have expectations been verified already?
Im unclear as to why this is failing. As far as I can tell, ScalaMock is complaining that it can't record invocations. But Im not clear why this issue is presenting.
Upvotes: 1
Views: 607