Junit Mocking TypeReference Return Type - junit

I am new to Junit , need help in mocking a simple method
public List < BingePageCacheDTO > getPages(String platform) {
return cacheMapper.fetchData(platform, CacheMaps.HOME_PAGE, new TypeReference < List < BingePageCacheDTO >> () {});
}
I am getting error in thenReturn method.
List < BingePageCacheDTO > bingePageCacheDTOList = new ArrayList < > ();
bingePageCacheDTOList.add(new BingePageCacheDTO().setPageName("test"));
bingePageCacheDTOList.add(new BingePageCacheDTO().setPageName("page"));
Mockito.when(cacheMapper.fetchData("platform", CacheMaps.HOME_PAGE, new TypeReference < List < BingePageCacheDTO >> () {})).thenReturn(bingePageCacheDTOList);
Error I am getting is :
error: no suitable method found for thenReturn(List<BingePageCacheDTO>)
})).thenReturn(bingePageCacheDTOList);
^
method OngoingStubbing.thenReturn(BingePageCacheDTO) is not applicable
(argument mismatch; List<BingePageCacheDTO> cannot be converted to BingePageCacheDTO)
method OngoingStubbing.thenReturn(BingePageCacheDTO,BingePageCacheDTO...) is not applicable
(argument mismatch; List<BingePageCacheDTO> cannot be converted to BingePageCacheDTO)
Can someone point my mistake here.

Related

element.length not working when using generics

My problem is this. I am passing arguments to a function that uses generics. For example I am passing element. I need to use element.length in the function but it gives me this error:
The property 'length' can't be unconditionally accessed because the receiver can be 'null'.
Try making the access conditional (using '?.') or adding a null check to the target ('!'). dartunchecked_use_of_nullable_value
void main(List<String> args) {
const List keyList = ['asd', 3, 'tyu', 67];
const List valueList = ['dfg', 'ert', 4, 'lkj'];
print(myMap(keyList, valueList));
}
Map myMap<K, V>(K key, V val) {
final Map<K, V> myMap = {};
for (int i = 0; i < key.length; i++) {
myMap[key[i]] = val[i];
}
return myMap;
}
I don't know if null aware operators can be used here, or if they solve the problem and how to use it.
You defined your generic types, but your parameters are lists of that type. You did not make this clear to your compiler. For your compiler, K is now of type List<dynamic> while what you wanted it to be is just dynamic.
Changing it to make it fit (my guess of) your requirements:
Map<K, V> myMap<K, V>(List<K> keys, List<V> values) {
final result = <K, V>{};
for (int i = 0; i < keys.length; i++) {
result[keys[i]] = values[i];
}
return result;
}
Please note that you are reinventing the wheel here. There already is a constructor that does this:
void main(List<String> args) {
const List keyList = ['asd', 3, 'tyu', 67];
const List valueList = ['dfg', 'ert', 4, 'lkj'];
print(Map.fromIterables(keyList, valueList));
}

Mapping custom strings found in JSON to POGO enum cases

In the context of a Grails application, we parse JSON into command objects. The automatic conversion from a JSON map to the POGO fails with an error like this:
org.codehaus.groovy.runtime.typehandling.GroovyCastException:
Cannot cast object '{<snip>}' with class 'groovy.json.internal.LazyMap' to class 'SomeCmd' due to:
java.lang.IllegalArgumentException: No enum constant Foo.my-bar
I narrowed it down to this plain Groovy MWE:
import groovy.json.JsonSlurper
enum Foo {
Bar("my-bar"),
Ista("my-ista")
final String s
private Foo(String s) {
this.s = s
}
}
class SomeCmd {
Foo foo
}
def some = new SomeCmd(new JsonSlurper().parseText('{ "foo" : "my-bar" }'))
println(some.foo)
This errors with
java.lang.IllegalArgumentException: No enum constant Foo.my-bar
This is expected -- so far, so good.
Now, following the documentation, I thought adding custom coercion from String to Foo might resolve the issue (also from here):
enum Foo {
<snip>
static Foo fromJsonString(String s) {
return values().find { it.s == s }
}
}
def oldAsType = String.metaClass.getMetaMethod("asType", [Class] as Class[])
String.metaClass.asType = { Class type ->
type == Foo ?
Foo.byJsonString(delegate as String) :
oldAsType.invoke(delegate, [type] as Class[])
}
However, the error persists. Apparently, JsonSlurper does not use coercion at all, given that
println("my-bar" as Foo)
prints Bar as desired.
What is going on here? How can I get JsonSlurper to pick the correct enum cases by something besides the case name?
PS: Fun fact, if we change the second-to-last line to
new JsonSlurper().parseText('{ "foo" : "my-bar" }') as SomeCmd
the script prints null.
Groovy will happily use custom setters to construct the object. With Foo.fromJsonString as given in the question, define SomeCmd like so:
class SomeCmd {
Foo foo
void setFoo(Object jsonObject) {
if (jsonObject == null || jsonObject instanceof Foo) {
this.foo = jsonObject
return
} else if (jsonObject instanceof String) {
Foo f = Foo.fromJsonString(jsonObject)
if ( null != f ) {
this.foo = f
return
}
}
throw new IllegalArgumentException("No Foo for $jsonObject")
}
}
Then, the code as given prints Bar as desired.
However, this doesn't help in Grails with parsing JSON into command objects -- Grails doesn't use coercion nor Groovy's map "magic". See this follow-up question.

Saving objects with writeObject: What objects can be saved using this method?

I'm working making my first foray into the exciting world of byteArrays!
End Goal
I want to save the positions and other properties of each game element (in this case, blocks in a breakout clone) as part of a level design feature for my app, and also to more easily design levels for the game.
Current Approach
Convert data from a Vector of custom class instances (the bricks) into a ByteArray and save that data to a text file. It seems like this is working fine up to this point (can't be sure until I successfully extract that data back into a Vector object, because the text file that gets saved is pure gobbledygook).
I load a level design by reading the text file into a byteArray and then doing writeObject() into a Vector with the intention of now having a vector that contains all the bricks (this is not working).
The Problem
When I try to run my load function, the file loads, and the byteArray gets "filled" with data, but when I try to do writeObject, I get all these errors(one copy of the following errors for each brick in the vector).
TypeError: Error #1034: Type Coercion failed: cannot convert Object#92cdcb9 to flash.geom.Point.
TypeError: Error #1034: Type Coercion failed: cannot convert Object#92cde09 to flash.geom.Point.
TypeError: Error #1034: Type Coercion failed: cannot convert Object#92df041 to flash.geom.ColorTransform.
TypeError: Error #1034: Type Coercion failed: cannot convert Object#92df161 to flash.geom.Point.
TypeError: Error #1034: Type Coercion failed: cannot convert Object#92df281 to flash.geom.Point.
TypeError: Error #1034: Type Coercion failed: cannot convert Object#92df431 to flash.media.SoundTransform.
TypeError: Error #2004: One of the parameters is invalid.
My custom brick class is an extension of the Sprite class. But it additionally has properties that depend on Point and ColorTransform objects. Oddly, nowhere in my custom class do I have any reference to or use of SoundTransform... so that error seems glaringly odd. I'll post my custom class if anyone wants to look at it.
My Save and Load Methods
private function saveLevelDesign(brVec:Vector.<LineTestBlock>):void{
trace("save");
var file:File = File.documentsDirectory;
file = file.resolvePath("AnimationFiles/brickLevels/lev_001.txt");
fileStream.open(file,FileMode.WRITE);
var bytes:ByteArray = new ByteArray();
bytes = brickArrayToByteArray(brVec);
//fileStream.close();
}
private function loadLevelDesign():void{
trace("loadLevelDesign");
var file:File = File.documentsDirectory;
file = file.resolvePath("AnimationFiles/brickLevels/lev_001.txt");
fileStream.open(file,FileMode.READ);
file.addEventListener(IOErrorEvent.IO_ERROR,ioError);
file.addEventListener(Event.COMPLETE, loaded);
file.load();
//fileStream.open(file,FileMode.READ);
}
private function ioError(ioE:IOErrorEvent):void{
trace("oops",ioE);
}
private function loaded(e:Event):void{
trace("loaded");
var bytes:ByteArray = new ByteArray();
fileStream.readBytes(bytes);
trace(bytes.length,"bytes length"); // 0 bytes length
var vec:Vector.<LineTestBlock> = new Vector.<LineTestBlock>;
for (var i:int = 4; i < _playerTurn._brickArray.length; i++){
vec.push(_playerTurn._brickArray[i]);
}
bytes.writeObject(vec);
trace(bytes.length,"bytes length"); // 53516 bytes length
destroyBricks(_playerTurn); // just removes all bricks on the stage
vec = byteArrayToBrickArray(bytes); // calling this function throws all those errors
trace("vector length:",vec.length); // vector length 208 (this is the correct number of bricks, so that's good)
}
My Byte Conversion Methods
private function byteArrayToBrickArray(bytes:ByteArray):Vector.<LineTestBlock>{
bytes.position = 0;
var blocks:Vector.<LineTestBlock> = bytes.readObject() as Vector.<LineTestBlock>;
trace(bytes.position);
return blocks;
}
private function brickArrayToByteArray(brVec:Vector.<LineTestBlock>):ByteArray{
var bytes:ByteArray = new ByteArray();
/*for (var i:int = 0; i < brVec.length; i++){
if (brVec[i]._break == true){
bytes.writeObject(brVec[i]);
}
}*/
bytes.writeObject(brVec);
return bytes;
}
Anyone see if I doing something wrong, or not understanding something?
Any object that implements IExternalizable or is not a DisplayObject can be saved in a ByteArray and restored from one, if you write both readExternal and writeExternal methods correctly. If an object does not implement IExternalizable, Flash will attempt to write it using public components visible to the code, and read it by assigning values read to public properties in the same order. Normally you should use the interface with anything that's more complex than a Vector.<int>. Therefore, you need to implement IExternalizable in your LineTestBlock class, writing and reading only those properties that are required. Also, you can only use this method with objects that have an empty constructor, because in IDataInput.readObject the object is first constructed, then values are assigned.
The manual on IExternalizable. For some reason you can't access it from the normal class tree, but it is there and the interface is working.
I'd change your approach by encapsulating all the vectors, SoundTransforms etc into a single class, say Level, then implement IExternalizable in it, which will then write all the simple data types in order (remember to write vector's lengths before the data!) when asked to, then read itself from a byte array and reconstruct all the internal data structure in the meantime. An example:
import flash.utils.*;
public class Level implements flash.utils.IExternalizable
{
private var blocks:Vector.<LineTestBlock>;
// something extra
public function writeExternal(output:IDataOutput):void {
var l:int=blocks.length;
output.writeInt(l);
for (var i:int=0;i<l;i++) {
//write all the blocks[i]'s properties in order to output
}
// same approach to write all the extra properties
}
public function readExternal(input:IDataInput):void {
var l:int=input.readInt();
blocks=new Vector.<LineTestBlock>();
for (var i:int=0;i<l;i++) {
// first read all the properties into any local variables in the VERY SAME order they were written
// then create an instance of LineTestBlock
var block:LineTestBlock=new LineTestBlock(...);
// required parameters for the constructor should be read before creating object
// then fill remaining properties to the created instance
blocks.push(block); // and reconstruct the array
}
// same approach to every property that was saved
// reconstruct everything else that's depending on the data read
}
}
And finally, you would likely need to perform a flash.net.registerClassAlias() call somewhere in your app's initialization to have your Level be recognized as a serializable class.
bytes.readObject() return an Object.
so problem is about convertin Object to Vector.<LineTestBlock> so you have to convert it your self
private function byteArrayToBrickArray(bytes:ByteArray):Vector.<LineTestBlock>{
bytes.position = 0;
// Edit : readObject() only presents an Object
var blocks:Object = bytes.readObject();
trace(bytes.position);
/* you have to convert all step by step
at first we have to assume blocks as a vector
best way to searching its items is using _for key in_
*/
var converted:Vector.<LineTestBlock> = new Vector.<LineTestBlock>(blocks.length);
for (var key:String in blocks) {
converted.push(objectToLineTestBlock(blocks[key]));
}
return converted;
}
as i dont know structure of your LineTestBlock class, i cant provide "objectToLineTestBlock" function exactly
Here is an Example that simulates your LineTestBlock Class
my own LineTestBlock Class
public class LineTestBlock
{
public var w:int;
public var loc:Point;
public var stf:SoundTransform;
public function LineTestBlock(_w:int, _loc:Point, _stf:SoundTransform)
{
w = _w;
loc = _loc;
stf = _stf;
}
}
main class that testing the solution.
what i do is just converting all Objects to what really they are
bytearray.readObject() convert all classes to pure Objects
public class ByteTest extends Sprite
{
public function ByteTest()
{
var save_vector:Vector.<LineTestBlock> = new Vector.<LineTestBlock>();
var block_item1:LineTestBlock = new LineTestBlock(200, new Point(-1, 1), new SoundTransform(0.5));
var block_item2:LineTestBlock = new LineTestBlock(400, new Point(-2, 2), new SoundTransform(0.25));
save_vector.push(block_item1);
save_vector.push(block_item2);
var load_vector:Vector.<LineTestBlock>;
var bytes:ByteArray = new ByteArray();
bytes.writeObject(save_vector);
// trace(bytes.position);
load_vector = objectToLineTestVector(bytes);
// now test to check if everything is OK
trace(load_vector[1].stf.volume); // must print 0.25
}
public function objectToLineTestVector(bytes:ByteArray):Vector.<LineTestBlock> {
bytes.position = 0;
var loadedObject:Object = bytes.readObject();
var blocks:Vector.<LineTestBlock> = new Vector.<LineTestBlock>();
for (var key:String in loadedObject) {
blocks.push(objectToLineTestBlock(loadedObject[key])); // loadedObject[key] is a block_item1 and could be converted
}
return blocks;
}
public function objectToLineTestBlock(obj:Object):LineTestBlock {
return new LineTestBlock(obj.w, objectToPoint(obj.loc), objectToSoundTransform(obj.stf));
}
public function objectToPoint(obj:Object):Point {
return new Point(obj.x, obj.y);
}
public function objectToSoundTransform(obj:Object):SoundTransform {
return new SoundTransform(obj.volume);
}
}

cannot cast from json value to orderMap

while trying to test physcis body editor loader (BodyEditorLoader.java) from here
i get this improper casting, below is the function
private Model readJson(String str) {
Model m = new Model();
OrderedMap<String,?> rootElem
= (OrderedMap<String,?>) new JsonReader().parse(str); //this line has casting problem
Array<?> bodiesElems = (Array<?>) rootElem.get("rigidBodies");
for (int i=0; i<bodiesElems.size; i++) {
OrderedMap<String,?> bodyElem = (OrderedMap<String,?>) bodiesElems.get(i);
RigidBodyModel rbModel = readRigidBody(bodyElem);
m.rigidBodies.put(rbModel.name, rbModel);
}
return m;
}
as the new version of libgdx does support Jsonvalue and with this help
private Model readJson(String str) {
Model m = new Model();
JsonValue map = new JsonReader().parse(str);
JsonValue bodyElem = map.getChild("rigidBodies");
for (; bodyElem != null; bodyElem = bodyElem.next()) {
RigidBodyModel rbModel = readRigidBody(bodyElem);
m.rigidBodies.put(rbModel.name, rbModel);
}
return m;
}
The parse method returns a JsonValue.
You're probably seeing this mismatch due to a newer build of Libgdx including a not-backwards-compatible change to the JSON code. See the blog post which includes this:
Only reading JSON is affected. If you use JsonReader, you’ll get back
a JsonValue instead of an OrderedMap.
You can either fix this by updating the code to work with a JsonValue or by downgrading to an older version of libgdx (before April 25th). If you're using nightly builds of Libgdx, definitely pay attention to the CHANGES and keep up with the blog (where most of the big changes are announced). Otherwise, its probably safer to stick to the "released" versions of Libgdx.

to return JSON using JAX-RS

I am trying to return JSON of SOLRDocList type which is :
{numFound=0,start=0,docs=[]}{"start":0,"empty":true,"class":"class org.apache.solr.common.SolrDocumentList","numFound":0}
However since I am using Service class as :
#POST
#Path("/userQuery")
#Consumes(MediaType.TEXT_PLAIN)
#Produces(MediaType.APPLICATION_JSON)
public SolrDocumentList userQuery(String p){
int sizy;
String stry;
StringBuilder sb = new StringBuilder();
SolrDocument doc = null;
SolrDocumentList docList = null;
List<String> arr = new ArrayList();
StringTokenizer token = new StringTokenizer(p,",");
while(token.hasMoreElements()){
stry = token.nextToken();
arr.add(stry);
}
Set<String> xrr = new HashSet<String>(arr);
SolrQuery query = new SolrQuery(createQuery(arr));
query.setIncludeScore(false);
query.setFields("country_code,last_name,raw_location");
query.setParam("wt", "json");
System.out.println(query);
QueryResponse qr = authorSearcher.query(query);
docList = qr.getResults();
return docList;
}
Error is :
SEVERE: A message body writer for Java class org.apache.solr.common.SolrDocumentList, and Java type class org.apache.solr.common.SolrDocumentList, and MIME media type application/json was not found
SEVERE: The registered message body writers compatible with the MIME media type are:
application/json ->
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$App
com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$App
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App
*/* ->
I want to know if there is any possible way to convert the SOLRDocList type which is JSON into the supported type to resolve this issue?
Thanks for your time !
I figured this out, since I am using solr4j , this library doesn't support JSON as a output , in such situation using external library or :
Map<Integer,Object> solrDocMap = new HashMap<Integer,Object>();
int counter = 1;
for(Map singleDoc: docList)
{
solrDocMap.put(counter, new JSONObject(singleDoc));
counter++;
}
try {
returnResults.put("docs",solrDocMap);
}
and when you want to return a JSON string instead going with 3rd party libraries , go with something like:
String x = ""+returnResults;
return x;