Test spray.io response - spray

I have the next code:
//models
case class Foo(name: String, age: Option[Int] = None)
//routing
trait FooRouting extends HttpService {
def index(foos: List[Foo]): twirl.api.Html = html.foo.render(foos)
val route =
path("") {
get { complete( index(Foo.all) } }
}
}
In index method, i render foo.scala.html template with Twirl.
I want test this behaviour:
//tests
class FooTests extends FunSpec with Matchers
with ScalatestRouteTest {
def actorRefFactory = system
val t0 = Foo("test0")
val t1 = Foo("test1")
it("test foo") {
Get() ~> r ~> check {
responseAs[List[Foo]] should be(List(t0, t1))
}
}
}
But i got error:
Tests.scala:49: could not find implicit value for evidence parameter of type spray.httpx.unmarshalling.FromResponseUnmarshaller[List[pack.Foo]]
[error] responseAs[List[Foo]] should be(List(t0, t1))
I define implicit method:
implicit val foo2response = new FromResponseUnmarshaller[List[Foo]] {
def apply(r: HttpResponse): Deserialized[List[Foo]] = {
???
}
}
But i do not know what i should write into body.
Thanks.

Related

Spock is using real methods even though object is mocked

In my app I use spock in version 2.0-M1-groovy-2.5. I have a problem that even though I mokced a class I get npe from the internals of mocked method.
I have simple class called ReactiveRestHighLevelClient which looks like this
open class ReactiveRestHighLevelClient(val restHighLevelClient: RestHighLevelClient, private val objectMapper: ObjectMapper) {
...
fun index(indexRequest: IndexRequest): Mono<IndexResponse> {
return Mono.create<IndexResponse> { sink ->
restHighLevelClient.indexAsync( // < -- HERE I GET THE NPE EVEN THOUGH THE METHOD IS MOCKED
indexRequest,
object : ActionListener<IndexResponse> {
override fun onFailure(e: Exception) {
e.printStackTrace()
sink.error(e)
}
override fun onResponse(response: IndexResponse) {
sink.success(response)
}
}
)
}
}
...
}
I have class ThreadModelElasticsearchService which uses the ReactiveRestHighLevelClient and looks like this:
#Component
class ThreadModelElasticsearchService(
private val objectMapper: ObjectMapper,
private val reactiveElasticsearchClient: ReactiveRestHighLevelClient,
private val extraFactsService: ExtraFactsService,
private val customerDataService: CustomerDataService,
rateLimiterRegistry: RateLimiterRegistry
) {
...
fun save(operationId: String, threadModel: ThreadModel): Mono<ThreadModel> {
val id = threadModel.threadId
?: ThreadModel.createKey(threadModel.partnerId, threadModel.customerId)
return reactiveElasticsearchClient
.index(
IndexRequest(ThreadModel.INDEX, ThreadModel.TYPE, id)
.source(objectMapper.writeValueAsString(threadModel), XContentType.JSON)
)
.thenReturn(threadModel)
.doOnNext { logger.info("[operation_id=$operationId] -- Saved : $it") }
.onErrorMap { e ->
logger.error("[operation_id=$operationId] -- Error calling elasticSearch", e)
ElasticRepositoryError(e)
}
.rateLimit(elasticRateLimiter)
}
...
}
Finally I have my test class called ThreadModelElasticsearchServiceTest which looks like this:
class ThreadModelElasticsearchServiceTest extends Specification {
ReactiveRestHighLevelClient reactiveElasticsearchClient = Mock()
... other mocks
ThreadModelElasticsearchService threadModelReactiveElasticsearchClient = new
ThreadModelElasticsearchService(objectMapper, reactiveElasticsearchClient, extraFactsService, customerDataService, RateLimiterRegistry.of(RateLimiterConfig.ofDefaults()))
def "should work"() {
given:
ThreadModel threadModel = new ThreadModel(...)
reactiveElasticsearchClient.index(_ as IndexRequest) >> Mono.just(indexResponse)
expect:
threadModelReactiveElasticsearchClient.save("should-work", threadModel).block()
}
When I run the tests I get execption like
java.lang.NullPointerException: null
at com.cb.elastic.search.api.elasticsearch.ReactiveRestHighLevelClient$index$1.accept(ReactiveRestHighLevelClient.kt:76)
which points to the body of the index method of the ReactiveRestHighLevelClient mock which is strange.
How to solve this ?

Xtext validation across (unreferenced) files

I am struggling to validate (non-duplication) globally, across multiple files that do not explicitly reference each other.
Consider the standard initally-generated grammar
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
Model:
greetings+=Greeting*;
Greeting:
'Hello' name=ID '!';
It is simple to validate that no file contains greeting for the same name.
package org.xtext.example.mydsl.validation
import org.eclipse.xtext.validation.Check
import org.xtext.example.mydsl.myDsl.Greeting
import org.xtext.example.mydsl.myDsl.Model
import org.xtext.example.mydsl.myDsl.MyDslPackage
class MyDslValidator extends AbstractMyDslValidator {
public static val LOCALLY_DUPLICATE_NAME = 'LOCALLY_DUPLICATE_NAME'
#Check
def checkGreetingLocallyUnique(Greeting greeting) {
for(greeting_ : (greeting.eContainer as Model).greetings) {
if(greeting!==greeting_ && greeting.name==greeting_.name) {
warning('Greeting duplication',
MyDslPackage.Literals.GREETING__NAME,
LOCALLY_DUPLICATE_NAME)
}
}
}
}
I do not understand how to validate non-duplication against all the files known to the global-index.
The stub of the method is
#Check
def checkGreetingGloballyUnique(Greeting greeting) {
for(greeting_ : /*???*/ ) {
if(greeting!==greeting_ && greeting.name==greeting_.name) {
warning('Global Greeting duplication',
MyDslPackage.Literals.GREETING__NAME,
GLOBALLY_DUPLICATE_NAME)
}
}
}
How do I get access to the global index from within the validator?
the easiest way for a local duplicate validation is to enable it in the workflow and regenerate the language (this does not check locally though)
validator = {
composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
}
to search the index
#Inject
IContainer.Manager containermanager;
#Inject
ResourceDescriptionsProvider resourceDescriptionsProvider;
public .... getAllEntitiesFor( EObject eObject ) {
....
IResourceDescriptions resourceDescriptions = resourceDescriptionsProvider.getResourceDescriptions( eObject.eResource() );
IResourceDescription resourceDescription = resourceDescriptions.getResourceDescription( eObject.eResource().getURI() );
List<IContainer> visiblecontainers = containermanager.getVisibleContainers( resourceDescription, resourceDescriptions );
for (IContainer container : visiblecontainers) {
for (IEObjectDescription eobjectDescription : container.getExportedObjects()) {
EObject eObjectOrProxy = eobjectDescription.getEObjectOrProxy();
.....
}
}
....
}
After much hacking, I obtained the following.
public static val GLOBALLY_DUPLICATE_NAME = 'GLOBALLY_DUPLICATE_NAME'
#com.google.inject.Inject
IResourceDescriptions iResourceDescriptions
#Inject
Provider<XtextResourceSet> resourceSetProvider;
#Check
def checkGreetingGloballyUnique(Greeting greeting) {
for (resourceDescriptions : iResourceDescriptions.allResourceDescriptions) {
for (_greetingDescription : resourceDescriptions.getExportedObjectsByType(MyDslPackage.Literals.GREETING)) {
val _greeting = resourceSetProvider.get.getEObject(_greetingDescription.EObjectURI, true) as Greeting
// don't use equality, ALWAYS not equal!!
if (greeting.eResource.URI != _greeting.eResource.URI) {
// this means distinct files, all greetings in same file have same uri
if (greeting.name == _greeting.name) {
warning('Global greeting duplication', MyDslPackage.Literals.GREETING__NAME,
LOCALLY_DUPLICATE_NAME)
}
}
}
}
}
Rewrite, based on #Christian Dietrich's comments, I have the following solution.
#Inject
IContainer.Manager containerManager;
#com.google.inject.Inject
IResourceDescriptions resourceDescriptions
#Inject
Provider<XtextResourceSet> resourceSetProvider;
#Check
def checkGreetingGloballyUnique(Greeting greeting) {
var greeting_description = resourceDescriptions.getResourceDescription(greeting.eResource.URI)
var visibleContainers = containerManager.getVisibleContainers(greeting_description, resourceDescriptions)
for (visibleContainer : visibleContainers) {
for (_greetingDescription : visibleContainer.getExportedObjectsByType(MyDslPackage.Literals.GREETING)) {
val _greeting = resourceSetProvider.get.getEObject(_greetingDescription.EObjectURI, true) as Greeting
// don't use equality, ALWAYS greeting != _greeting !!
if (greeting.eResource.URI != _greeting.eResource.URI) {
// this means distinct files, all greetings in same file have same uri
if (greeting.name == _greeting.name) {
warning('Global greeting duplication', MyDslPackage.Literals.GREETING__NAME,
GLOBALLY_DUPLICATE_NAME)
}
}
}
}
}

Xtext: Use EClass in XExpression

I am writing on a Xtext grammar that uses XExpressions and also operates on Eclasses. Now I want to also be able to access Eclasses from the XExpression, for example I write an expression like this:
Eclass1.attribute1 = Eclass2.attribute1
I would like to know, how I can use the Eclass from within the XExpression?
Grammar
grammar org.xtext.example.mydsl.Mydsl with
org.eclipse.xtext.xbase.Xbase
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate mydsl "http://www.xtext.org/example/mydsl/Mydsl"
Model:
(operations += Operation)*;
terminal ATTR : ID ('.' ID)+;
Operation:
'operation' left=[ecore::EClass|ATTR] 'and' right=
[ecore::EClass|ATTR] 'defined' 'as' condition=XExpression
;
Inferrer/ Infer method
def dispatch void infer(Model element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
acceptor.accept(element.toClass("example.mydsl")) [
for (operation : element.operations) {
left = operation.left
right = operation.right
if (left.eIsProxy()) {
left = EcoreUtil.resolve(left, operation) as EClass
}
if (right.eIsProxy()) {
right = EcoreUtil.resolve(right, operation) as EClass
}
//field for right class left out, but works the same
members += left.toField(left.name,typeRef(left.EPackage.name+"."+left.name))
members += operation.toMethod("conditionExpr",
typeRef(Void.TYPE)) [
body = operation.condition
]
}
]
}
RuntimeModule
class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
def Class<? extends ImplicitlyImportedFeatures> bindImplicitlyImportedTypes() {
return MyImportFeature
}
}
MyImportFeature
class MyImportFeature extends ImplicitlyImportedFeatures{
override protected getStaticImportClasses() {
(super.getStaticImportClasses() + #[PackageFromWorkSpace]).toList
}
}
I Am not sure if i get your question.
Ususally EMF generates constants for EAttributes so if you want to access the attributes themselfs
so you could either do
MyDslPackage.Literals.GREETING__NAME
or
MyDslPackage.eINSTANCE.getGreeting_Name()
can you give some more hints on what you actually want to do
update: here is a snippet on how to get a java class from a reference to an eclass
Thingy:{
val EClass eclazz = f.clazz
val uri = EcorePlugin.getEPackageNsURIToGenModelLocationMap(true).get(eclazz.EPackage.nsURI)
val rs = new ResourceSetImpl
val r = rs.getResource(uri, true)
r.load(null)
val p = r.contents.head
if (p instanceof GenModel) {
val genClass = p.findGenClassifier(eclazz)
if (genClass instanceof GenClass) {
println(genClass.qualifiedInterfaceName)
members+=f.toField(eclazz.name, genClass.qualifiedInterfaceName.typeRef)
}
}
}

List of Class Objects operation in Dart

Have an issue in the below chunk of code.
class Events
{
// some member variables
}
class SVList
{
String name;
int contentLen;
List<Events> listEvents;
SVList()
{
this.name = "";
this.contentLen = 0;
this.listEvents = new List<Events>();
}
}
class GList
{
List<SVList> listSVList;
GList(int Num)
{
this.listSVList = new List<SvList>(num);
}
}
function f1 ()
{
//array of class objects
GList gList = new GList(num);
}
Not able to find "listEvents" member after GList constructor is called. Am I missing anything here.
Referencing glist.listSVList[index] --> do not find member variable 'listEvents'. Any pointers appreciated.
To elaborate , no member variable with 'glist.listSVList[index].listEvents' is found.
you have a typo here:
this.listSVList = new List<SvList>(num); // <== SVList not SvList
function seems wrong here
function f1 () { ... }
in this case you use function as a return type
another typo:
GList(int Num) // <== Num (uppercase)
{
this.listSVList = new List<SvList>(num); // <== num (lowercase)
}
this code worked:
class Events {
// some member variables
}
class SVList {
String name;
int contentLen;
List<Events> listEvents;
SVList() {
this.name = "";
this.contentLen = 0;
this.listEvents = new List<Events>();
}
}
class GList {
List<SVList> listSVList;
GList(int num) {
this.listSVList = new List<SVList>(num);
}
}
main() {
//array of class objects
GList gList = new GList(5);
gList.listSVList[0] = new SVList();
gList.listSVList[0].listEvents.add(new Events());
print(gList.listSVList[0].listEvents.length);
}
What editor are you using?
DartEditor showed all errors immediately after I pasted your code.
Lists in Dart can now be stated as
List<Object> array = []

how to mock a closure method

I have a service class defined as follows
class MyService {
def otherService;
def performService( ) {
Navigator.navigate( retrieveData, { otherService.doSomething(it) } );
}
def retrieveData = { Integer offset, Integer maxRows
DomainObject.list(offset,maxRows);
}
}
Navigator.navigate( Closure retriever, Closure processor ) {
def offset=0;
def batchsize=100;
while( (data=retriever(offset,batchsize)) ) {
if(data.size()==0) break;
data.each { processor(it) }
offset += data.size();
}
}
In my tests, I would like to mock the retriveData to retrieve mocked objects
#TestFor(MyService)
class MyServiceSpec extends Specification {
def "test retriever"() {
given:
service.otherService = Mock(OtherService);
service.metaClass.retrieveData = { Integer offset, Integer maxRows ->
if(offset==0) return [ Mock(DomainObject), Mock(DomainObject) ]
else return []
}
when:
service.performService();
then:
2 * otherService.doSomething(_);
}
}
It turns out that the test is not picking up the mocked retrieveData, instead it always picks up the MyService.retrieveData closure, wondering what is the right approach to mock a closure method..
Seems that it's because retrieveData is a field, not a method. Can you try:
given:
...
service.retrieveData = { Integer offset, Integer maxRows ->
...
}

Resources