I have a trait that looks like this
private[name] trait HttpIssuer extends HttpIssuerImpl with JsonApi with Logging {
def credentials: ApiCredentials
def maxAllowedQuota: Int
def minHour: Option[Int]
def maxHour: Option[Int]
implicit def session: Session
val throttling = new Throttling(maxPerSecond = 5, maxPerMinute = 300)
val log = LoggerFactory.getLogger(getClass)
val hasTimeRange = minHour.isDefined || maxHour.isDefined
var response: Option[MarketoIdentityResponse] = None
var authorization: Option[String] = response.map(_.accessToken)
var previouslyUsedApiQuota: Int = 0
var numberOfQueries: Int = 0
override def executeRequest(request: RestRequest): ApiResponse = {
executeRequest(request, 0)
}
def executeRequest(request: RestRequest, retries: Int = 0): ApiResponse = {
if (numberOfQueries + previouslyUsedApiQuota > maxAllowedQuota) {
warn("Exceeded max allowed API quota of " + maxAllowedQuota +
" based on previously used quota of " + previouslyUsedApiQuota + " and new API usage of " + numberOfQueries)
System.exit(0)
}
}
}
I’m trying to test the executeRequest method, to make sure it fails when numberOfQueries + previouslyUsedApiQuota > maxAllowedQuota, numberOfQueries = 0 and previouslyUsedApiQuota = 0 so if maxAllowedQuota = -1 it should fail, my test is below
@Test
def test_executeRequestExits: Unit = {
val creds = ApiCredentials (
instanceId = "dummy-instance-id",
clientId = "dummy-client-id",
clientSecret = "String",
soapUserId = "String",
encryptionKey = "String"
)
val mockRequest = mock(classOf[RestRequest])
val issuer = new HttpIssuer {
override val credentials: ApiCredentials = creds
override implicit val session: Session = new Session {
override def isInTransaction: Boolean = false
override def tenant: String = "test-tenant"
override def jdbcSession(): JdbcSession = throw new UnsupportedOperationException("Not implemented for testing")
}
// give negative quota so I enter error handling
override val maxAllowedQuota: Int = -1
override val minHour: Option[Int] = Some(1)
override val maxHour: Option[Int] = Some(2)
}
val mockApiFailure = mock(classOf[ApiFailure])
when(mockApiFailure.code).thenReturn("601") // Access token expired
when(MarketoHttpIssuer.failureGauge(any())(any())).thenReturn(any())
val executeRequestReturn = issuer.executeRequest(mockRequest)
class NoExitSecurityManager extends SecurityManager {
var exitCalled = false
var exitStatus: Option[Int] = None
override def checkExit(status: Int): Unit = {
exitCalled = true
exitStatus = Some(status)
}
}
val securityManager = new NoExitSecurityManager
// Verify that System.exit was called with 0
assert(securityManager.exitCalled)
assert(securityManager.exitStatus.contains(0))
// Restore the original security manager
System.setSecurityManager(null)
}
The problem I’m having is that when I initialize the trait I get a null pointer exception. I stepped through the code and the problem seems to be on this line
val hasTimeRange = minHour.isDefined || maxHour.isDefined
But in the trait I set them both to Some(1) so I am not sure why the trait is setting them to null? Maybe I’m doing something wrong?
Also, when I put a break point in this line
val issuer = new MarketoHttpIssuer
, it seems to hover into it more than once, maybe I’m misunderstanding how to properly initialize a trait?