How can I pass enum values as an argument to an invoke in codemodel? - sun-codemodel

I am trying to create a JInvocation like :-
driver.manage().timeouts().implicitlyWait(10L, (TimeUnit.SECONDS));
This is the block of code that I use to generate the same :-
public static JInvocation implicitWait(JVar driverJVar, Long implicitWaitTime, TimeUnit timeUnit) {
JClass timeUnitType = (JClass) BasicUtility.getReferenceForClass(TimeUnit.class);
JExpression jExpression = JExpr.direct(timeUnitType.name().concat(".").concat(timeUnit.name()));
return driverJVar.invoke("manage").invoke("timeouts").invoke("implicitlyWait").arg(JExpr.lit(implicitWaitTime)).arg(jExpression);
}
This works perfectly, the only problem being that TimeUnit doesn't create an import statement for this. I have to put it manually. Is there any other way to use enums values and pass as arguments?

Found a solution to it. We can do it using the staticRef method of JClass. This would bring the import statement automatically.
JClass timeUnitType = (JClass) CodeModelUtility.getReferenceForClass(TimeUnit.class);
return driverJVar.invoke("manage").invoke("timeouts").invoke("implicitlyWait").arg(JExpr.lit(implicitWaitTime)).arg(timeUnitType.staticRef(timeUnit.name()));

Related

Is it possible to create a new jobject of a java listener in JNI?

In Android Studio MainActivity, I write something like
int itemA_num = 0;
int itemB_num = 0;
ABCListener mabclistener = new ABCListenter() {
#Override
public void onEventActivated(CustomResult result) {
//do sth secret e.g.
itemA_num ++;
}
}
ABCobject mabcobject = (ABCobject) findviewById(R.id.abcobject1);
mabcobject.setListener(mabcListener);
I don't want people to decompile my APK and modify the code by amending the value or adding something like this:
ABCListener mabclistener = new ABCListenter() {
#Override
public void onEventActivated(CustomResult result) {
//do sth secret e.g.
itemA_num += 10000; //possibly some general name read by those guys and modified as int1 +=10000;
itemB_num += 500; //possibly some general name read by those guys and added this line int2 +=500;
}
}
So I want to use JNI with Cmake. Inside a .cpp file, I want to create the Class Object, findviewById, setListener and create the ABCListener.
I know using the format
jclass cls = (jclass) env->FindClass("abc/def/GHI");
jmethodID mid = (jmethod) env->GetMethodID(cls, "methodname", "(xxxx)yyy");
jobject obj = (jobject) env->CallObjectMethod(cls, mid, params);
However, if I want to write code about ABCListener and make a jobject of it, I don't know how and where to tell the machine I am going to write some code relating to #Override public void onEventActivated(CustomResult result) { ... }. I also want to add some lines of code inside the response in JNI.
I have found a website "similar" to this question but it is from 2011 and about Runnable. https://community.oracle.com/tech/developers/discussion/2298550/overriding-interface-methods-via-jni
I don't know if it still works in 2021.
First, define a new class on the Java side:
class NativeABCListener implements ABCListener {
#Override public native void onEventActivated(CustomResult result);
}
Next, create an instance of NativeABCListener, either in Java or in native code, and attach it to your mabcobject. You know how to do this so I will not repeat it.
On the native side, you simply define a C++ method with the appropriate name:
JNIEXPORT void JNICALL Java_your_package_NativeABCListener_onEventActivated(JNIEnv *env, jobject thiz, jobject result) {
...
}
If you need multiple ABCListeners that do different things, you can choose to create multiple NativeABCListener classes (each with their own corresponding native function), or you can modify NativeABCListener to store a C++ function pointer in a Java long field. In the ..._onEventActivated function you then extract the field from thiz and call it like a regular functino pointer.

How to create Single.just(Void)

I am writing some unit test cases for my application. I want to mock MongoClient update method, but the update returns Single<Void>.
when(mongoClient.rxUpdate(anyString(), any(JsonObject.class), any(JsonObject.class)))
.thenReturn(Single.just(Void))
Now Single.just(Void) doesn't work, what is the correct way of doing it?
--UPDATE--
So I am writing unit test for updateUserProfile method and for that I have mocked service. But the service.updateAccount method return is something I am not able to mock.
//Controller class
public void updateUserProfile(RoutingContext routingContext){
// some code
service.updateAccount(query, update)
.subscribe(r -> routingContext.response().end());
}
//Service Class
public Single<Void> updateAccount(JsonObject query, JsonObject update){
return mongoClient.rxUpdate("accounts", query, update);
}
Because the return type of mongoClient.rxUpdate is Single<Void>, I am not able to mock that part.
For now the workaround which I have figured out is:
public Single<Boolean> updateAccount(JsonObject query, JsonObject update){
return mongoClient.rxUpdate("accounts", query, update).map(_void -> true);
}
But this is just a hacky way of doing it, I want to know how can I exactly create Single<Void>
Having a method returning Single<Void> may raise some concerns, as some users have already expressed their view on this in the comments.
But if you are stuck with this and you really need to mock it (for whatever reason), there are definitely ways to create a Single<Void> instance, for example you could use the create method of the Single class:
Single<Void> singleVoid = Single.create(singleSubscriber -> {});
when(test.updateAccount(any(JsonObject.class), any(JsonObject.class))).thenReturn(singleVoid);
Single<Void> result = test.updateAccount(null, null);
result.subscribe(
aVoid -> System.out.println("incoming!") // This won't be executed.
);
Please note: you won't be able to actually emmit a Single item, since Void can't be instantiated without reflection.
A trick that could eventually work in some cases is to ommit the generic type argument and emmit an Object instead, but this could lead easily to a ClassCastException. I would not recommend to use this:
Single singleObject = Single.just(new Object());
when(test.updateAccount(any(JsonObject.class), any(JsonObject.class))).thenReturn(singleObject);
Single<Void> result = test.updateAccount(null, null);
// This is going to throw an exception:
// "java.base/java.lang.Object cannot be cast to java.base/java.lang.Void"
result.subscribe(
aVoid -> System.out.println("incoming:" + aVoid)
);
And of course you could use reflection as well (as already suggested by Minato Namikaze):
Constructor<Void> constructor = Void.class.getDeclaredConstructor(new Class[0]);
constructor.setAccessible(true);
Void instance = constructor.newInstance();
Single<Void> singleVoidMock = Single.just(instance);
when(test.updateAccount(any(JsonObject.class), any(JsonObject.class))).thenReturn(singleVoidMock);
Single<Void> result = test.updateAccount(null, null);
result.subscribe(
aVoid -> System.out.println("incoming:" + aVoid) // Prints: "incoming:java.lang.Void#4fb3ee4e"
);

How to resolve "named type" in NSubstitute?

I am using IUnityContainer for Registering the types for resolving later.
I have registered the types as below:
// Register a "named type" mapping
container.RegisterType<IProcessHelper, FirstResponseHelper>("FirstResponseHelper");
container.RegisterType<IProcessHelper, SecondResponseHelper>("SecondResponseHelper");
Hence, I could able to use as below in one of my constructor:
public Finish(
IUnitOfWork unitOfWork ,
ILog logger,
..........
[Dependency("FirstResponseHelper")] IProcessHelper firstResponseHelpe,
[Dependency("SecondResponseHelper")] IProcessHelper secondResponseHelper
)
{
.........
_firstResponseHelpe = firstResponseHelper;
_secondResponseHelper = secondResponseHelper;
}
...and would like to get it resolved using Substitute, something-like "below". But by passing the "name" => "FirstResponseHelper" is not allowed in Substitute! :(
// Trying to resolve in UnitTest, looks like below (passing name)
IProcessHelper firstResponseHelper = Substitute.For<IProcessHelper>("FirstResponseHelper")
IProcessHelper secondResponseHelper = Substitute.For<IProcessHelper>("SecondResponseHelper")
I need to call a method from FirstResponseHelper & SecondResponseHelper, from my UnitTest (MSTest).
Hence, I need to get it resolved using Substitute.For<> for the "named type" interface.
I'm assuming that you want to register a Substitute as named registration so that you can resolve Finish. If that is the case then you can use an InjectionFactory to return the substitute:
container.RegisterType<IProcessHelper>("FirstResponseHelper",
new InjectionConstructor(c => Substitute.For<IProcessHelper>()));
container.RegisterType<IProcessHelper>("SecondResponseHelper",
new InjectionConstructor(c => Substitute.For<IProcessHelper>()));
As an aside I wouldn't use the [DependencyAttribute] and instead remove those attributes and define an InjectionConstructor that passes in the correct dependencies:
container.RegisterType<Finish>(
new InjectionConstructor(
new ResolvedParameter<IUnitOfWork>(),
new ResolvedParameter<ILog>(),
new ResolvedParameter<IProcessHelper>("FirstResponseHelper"),
new ResolvedParameter<IProcessHelper>("SecondResponseHelper")));
or an InjectionFactory that does something similar:
container.RegisterType<Finish>(
new InjectionFactory(c =>
{
return new Finish(c.Resolve<IUnitOfWork>(),
c.Resolve<ILog>(),
c.Resolve<IProcessHelper>("FirstResponseHelper"),
c.Resolve<IProcessHelper>("SecondResponseHelper")
}));

call back (reinstantiation) of a module through another module at run time with change of parameter

I am using this module hierarchy :
Node: {udpApp[0]<->udp<->networkLayer->wlan[0]} and wlan[0]: {CNPCBeacon<->mac<->radio}
With some ini parameter for udpApp as:
I have given some initial parameter in the ini file for udpApp as :
**.host*.numUdpApps = 2
**.host*.udpApp[0].typename = "UDPBasicApp"
**.host*.udpApp[0].destAddresses = "gw1"
**.host*.udpApp[0].startTime = 1.32s
**.host*.udpApp[0].stopTime = 1.48s
But at run time I want to change the startTime and stopTime for udpAPP[0] through CNPCBeacon module.
Hence I changed CNPCBeacon.cc as:-
cModule* parentmod = getParentModule();
cModule* grantParentmod = parentmod->getParentModule();
cModule* udpmod = grantParentmod->getSubmodule("udpApp",0);
double varHoldingStartTime = udpmod->par("startTime").doubleValue();
double varGoldingStopTime = udpmod->par("stopTime").doubleValue();
varHoldingStartTime = SIMTIME_DBL(4.2);
varGoldingStopTime = SIMTIME_DBL(4.5);
udpmod->par("startTime").setDoubleValue(varHoldingStartTime);
udpmod->par("stopTime").setDoubleValue(varGoldingStopTime);
EV<<"New start and stop time is "<<udpmod->par("startTime").str()<<"\t"<<udpmod->par("stopTime").str()<<endl;`
Which successfully change the parameters. However it doesn't initiate the udpApp[0] module again. So I try to use dynamic casting of this module as:
UDPBasicApp* udpBasicMod = dynamic_cast<UDPBasicApp*>(udpmod);
sendTimer = new cMessage("sendTimer");
scheduleAt(iniSchduleTime, sendTimer);
and it resulted in following error:-
error in module (CNPCBeacon) BSoneNode.gw1.wlan[0].CNPCBeacon (id=23) at event #1496, t=4: scheduleAt() of module (UDPBasicApp)BSoneNode.gw1.udpApp[0] called in the context of module (CNPCBeacon)BSoneNode.gw1.wlan[0].CNPCBeacon: method called from the latter module lacks Enter_Method() or Enter_Method_Silent()?.
Is there also any other way to instantiate a module through other sub module.
Thanks for this help.
The solution for reinitializing a module (target module) through another module (requesting module) is creating handleParamterChange() function in target module. handleParameterChange() is used to reread the changed parameter at tun time. However it won't start scheduleAt() event to reinitialize the event for the target module. So I just added the scheduleAt() event in this function as :
void UDPBasicApp:: handleParameterChange(const char* parname)
{
if(parname)
{
if((strcmp(parname, "startTime")==0) &&
(startTime != par("startTime").doubleValue())
startTime = par("startTime").doubleValue();
if(strcmp(parname,"stopTime")==0)&&
(stopTime != par("stopTime").doubleValue())
{
stopTime = par("stopTime").doubleValue();
selfMsg->setKind(START);
scheduleAt((simtime_t)(startTime), selfMsg);
}
}
Note here that selfMsg is defined in the initialize function of UdpBasciApp.cc in INET framework.
I am a bit lost in the hierarchy and relation between your modules and sub-modules, however I think if your want to create (or re-create) a module dynamically you could use the built-in approach suggested by OMNeT++: https://omnetpp.org/doc/omnetpp/manual/usman.html#sec186
Maybe you could use the one-liner directly once you have (re-)defined the parameter values:
cModuleType *moduleType = cModuleType::get("foo.nodes.WirelessNode");
cModule *mod = moduleType->createScheduleInit("node", this);
On the other hand you error message complains about: Enter_Method() and/or Enter_Method_Silent()
These macros should be used in case that you try to call a function of a module (example X::get()) from within another module:
Y::doSmthWithXsGet()
{
x->get();
}
For this to work Enter_Method() (or Enter_Method_Silent()) has to be written in the beginning of X::get()
X::get()
{
Enter_Method();
/* rest of the code */
}
You can read Direct Method Calls section of the OMNeT++ userman to see what that means.
The weird thing is that you are getting this error for the scheduleAt() method, which is a method which belongs to the fundamental OMNeT++ class cSimpleModule. That means, in order to use this method in your class you will have to inherit from cSimpleModule in your class definition.
Maybe simply doing something like:
class MyCurrentClass: public cSimpleModule
{
/* further class definition */
};
... could solve your prob.

How to mock private methods in controller in grails 2.2.4

I have a private method which was mocked in grails 1.3.7 using metaclass but now that I upgraded grails version to 2.2.4, the same mocking fails.
Method to test has a call to private method
private def MyPrivateMeth1(def arg1, def arg2) {
...
}
Mocking is something like this
MyController.metaClass.private.MyPrivateMeth1 = { a, b ->
...
}
Try using the #TestFor annotation, which will give you a controller variable. You can then alter the metaclass of that, as well as incorporating Kamil Mikolajczyk and araxn1d's suggestions. So, your whole test should probably look like this:
#TestFor(MyController)
class MyControllerTests {
setup() {
controller.metaClass.MyPrivateMeth1 = {def arg1, def arg2 ->
//you can make your mocked method return whatever you wish here
return [key1: "foo", key2: "bar"]
}
}
void testForSomething() {
//Some code here that invokes an action or two in your controller which in turn invokes the private method
}
}
Make sure to have def (or String, Long, or whatever declaration you use) on the arguments of your mock method precisely as they are on the actual private method in the controller, or your test will try to use the class's normal private method first.
Here's a similar test in Spock:
import spock.lang.Specification
import spock.lang.Unroll
import grails.test.mixin.*
import org.junit.*
#TestFor(MyController)
class MyControllerSpec {
def "test that thing"() {
setup:
controller.metaClass.MyPrivateMeth1 = {def arg1, def arg2 -> return someOutput }
expect:
controller.someAction() == expectedRender
where:
someOutput | expectedRender
[key1: "foo", key2: "bar"] | "expected render from controller"
}
}
It seems that you need to declare types of closure arguments (its 100% if that arguments have actual types, for example Long, but not sure about def, but you need to try):
MyController.metaClass.MyPrivateMeth1 = { def a, def b -> ... }
I believe you don't need the .private. part
MyController.metaClass.MyPrivateMeth1 = { a, b -> ... }
should be enough, however I would specify parameter types explicitly
And, by the way, you should keep java naming conventions - methods names should start with lowercase character
For unit tests I have used Reflection for private methods. Something similar to this should work...
Method method = BehaviourService.getDeclaredMethod("behaviourValidConstraints",User.class,Behaviour.class)
method.setAccessible(true)
boolean valid = ((Boolean)method.invoke(service, user,b)).booleanValue()
First you get the method with getDeclaredMethod setting the name and the parameter types, you set it accesible and finally tou call it with method.invoke passing the object that has the method and the parameters. The result is an Object so you have to cast it.
I know there must be a better solution, but this one is the only one I've found that works
Edit: Sorry, what's above is for making a call to a private method.
I think that I've mocked a private method before just doing...
MyController.metaClass.myPrivateMeth1 { a, b ->
...
}
Just like you wrote it but without the .private and the = sign. Also, as Kamil said, you should follow java naming conventions for method names...