I created a trait: “RestfulService” whose purpose is to build requests where knowledge about the request details are embedded in the object.
`
trait RestfulService {
protected def description : String // the description that Gatling will associate the request with for reporting
protected def method : String // the HTTP request method
protected def url : String // the URL to request
protected def body : String // the request body to send
// add request headers
protected var requestHeaders: Map[String,String] = Map()
protected def header( key: String, value: String ) = {
requestHeaders += ( key → value )
this
}
// add query parameters
protected var queryParams: Map[String,Any] = Map()
protected def queryParameter( key: String, value: Any ) = {
queryParams += ( key → value )
this
}
// add form parameters
protected var formParams: Map[String,Any] = Map()
protected def formParameter( key: String, value: Any ) = {
formParams += ( key → value )
this
}
// …
}
`
The intent is to create classes with this trait which creates public methods which are implemented by using these methods. Problem is, the return type of “this” is RestfulService, and not the true type of the object itself.
What is the scala syntax for saying that the return type of the method is the type of the object on which the method was called?
What happens is, the return type of .endDate does not contain someProperty.
I kept digging, and I found “this.type” in order to specify that the return type needs to be the type of the object. That seems to solve the problem.
I hear you about the use of “var” - because the code is only run during scenario construction, it should be okay. But at the same time, I wouldn’t mind converting it to be more “safe”. What would that look like?
I hear you about the use of "var" - because the code is only run during
scenario construction, it should be okay.
Not if you use elements as prototypes for building other elements (which
you can do with Gatling DSL elements as they're all immutable).
A few months ago, someone was doing the same kind of mutable DSL like you
and didn't understand why he had this kind of issue:
val request = myOwnCustomMutableRequestDSL
exec(request) // OMG, why does this send foo?! Gatling is buggy for sure!!!
.exec(request.setSomeAdditionalParameter("foo"))
You have to make all your DSL methods return new instance and not share any
mutable state, just like Gatling DSL. Case classes copy method is just
amazing for this.