In java we would do the following:
verify(myTestObject).execute(any(Callback.class))
In kotlin if I use any(Callback::class) I get "too many arguments for public fun any(): T defined in com.nhaarman.mockitokotlin2".
You have to specify the class as generic type argument:
verify(myTestObject).execute(any<Callback>())
Or, due to type inference, you can leave it out:
verify(myTestObject).execute(any())
Related
I am using Mockito for unit testing. And there are many matchers like anyString(), anyBoolean() in Mockito. But suppose if I have a custom enum like
Enum LoginType.java
//LoginType.java
public enum LoginType {
FACEBOOK,
EMAIL,
GOOGLE
}
In one of the method arguments I need to pass an instance of LoginType. How do I pass the argument without explicitly passing LoginType.FACEBOOK or LoginType.GOOGLE. Something like anyString(). Any hint in that direction will be useful.
For any behavior, just calling Matchers.any() may be good enough on Java 8. That's when parameter type inference came out.
You might also choose Matchers.any(LoginType.class), which has pure any() behavior in Mockito 1.x but will provide type checking in Mockito 2.0 and beyond. In either case, passing in the class literal will help Java get the type information you need for inference.
For related problems:
If you have a generic type, the class literal isn`t enough either; you need to specify it as an explicit method parameter:
Matchers.<YourContainer<YourType>>any();
...or extract to a static helper method, which you need to do instead of a constant or local variable because Mockito matchers work via side effects:
public static LoginType anyLoginType() {
return Matchers.any();
}
Finally, for future readers who might be here to implement custom matching logic, look for Matchers.argThat or MockitoHamcrest.argThat to adapt a Hamcrest-style Matcher object into a Mockito method call.
I asked here: https://stackoverflow.com/questions/36385548/how-to-programmatically-construct-a-lambda-in-java-8 but I wanted to know if there are alternatives to construct lambdas in clojure.
For the use case, I'm attempting to wrap the rethinkdb library: http://www.rethinkdb.com/api/java/#map
I may be wrong, but in the rethinkdb driver, somehow the lambdas are compiled into ast syntax that are converted to js and sent to the database. I believe I need to somehow explicitly create a lambda. http://www.rethinkdb.com/blog/lambda-functions/
so this quesion How to implement lambda as a function called "lambda" in Clojure? only shows how to use a function, not a lambda.
Lambdas are just a syntax sugar, like clojure macros. You can NOT use macros in java, or the "lambda syntax" of java in clojure. But you can create in clojure the object that the java lambda syntax creates.
That is, in java the lambda syntax creates an object that implements the interface according to the type in the method. That interface has a single non-default and non-static method.
If you want to construct a "java lambda" in clojure, what you really need to do is create an object implementing that interface.
Functional interface:
https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html
How you see the lambdas as an argument:
How do I define a method which takes a lambda as a parameter in Java 8?
(Mandatory Newbie Disclaimer)
I'm trying to write a rule that fires whenever an object within a (scala) list matches a condition. The issue here is that the list is actually an Option(List[TypeA])... (Also, I realise it isn't best practice to store lists in working memory, but I can't do otherwise given the circumstances)
The case classes I'm using have the following sort of structure:
TypeA {
arg1 : Option[List[TypeB]]
}
with
TypeB {
value : String
}
I've written a rule similar to this:
when
$a : TypeA($l : arg1)
$b : TypeB() from $l.get()
then
System.out.println($b)
I've tried this out without the ".get()" only to get an object of type Some().
Using the ".get()", I have managed to return the contents of the Option but it doesn't seem to match the expected type (List[TypeB]). Instead the type of the value returned seems to be scala.collection.immutable.$colon$colon
Any ideas on what the problem is? And if there is any proper way to handle Options in Drools?
Since you are doing a lot of Java and Scala interop, I suggest you make yourself very familiar with the Scala's javaconverters functionality. This handy collection of utilities allows you to convert Scala collections to Java collection and vice versa.
In your case, I think you need to convert from a Java collection to a Scala collection. Try the following:
import scala.collection.JavaConverters._
val myScalaList = $b.asScala.toList
Example from the documentations:
import scala.collection.JavaConverters._
val sl = new scala.collection.mutable.ListBuffer[Int]
val jl : java.util.List[Int] = sl.asJava
val sl2 : scala.collection.mutable.Buffer[Int] = jl.asScala
assert(sl eq sl2)
An additional problem you have is that of mutable and immutable data structures. The standard list structure in Java is mutable but by default Scala offers you an immutable list unless you explicitly indicate that you want a mutable list. Therefore, there will be some impedance mismatch when doing naive conversions between the two worlds.
As I have mentioned in an earlier post, you can avoid yourself many issues by creating Java classes for the entities that you need to push into Drools. Mixing Java classes with Scala classes in Scala based projects is not an issue.
An alternative method is to create a function in your Scala case class which converts the Scala collection to a Java collection using the asJava method and returns it. In your DRL file whenever you need to reference that scala collection, call this method so that you get a Java collection instead.
Ideally, JBoss Drools, if they so choose, need to either enhance their current compiler to deal with Scala types better or make a dedicated Drools Scala compiler which will not mangle the Scala types.
The only thing I can think of to try:
when
$a : TypeA($l : arg)
$b : TypeB() from (ArrayList)$l.get() // or some other Java *-List
then
System.out.println($b)
Worth another try:
when
$a : TypeA($l : arg)
$b : TypeB() from $l.get()asJava()*-List
then
System.out.println($b)
As a part of unit test I need to mock a void function(Which accept any non-primitive paramter. e.g. MAP) call with any argument.
mockObj.myMethod(<anyObject>)
Is it possible to do this with EasyMock?
Use either of the anyObject methods: anyObject() or anyObject(T)
So
expect(mockObj.myMethod(anyObject()));
See the Flexible Expectations with Argument Matchers section of the documentation
I have a class that uses functors as units of work. It accepts a reference to a functor in its Run() method. To allow this class to operate on any functor, all these functors must derive from my base functor class which looks like this:
class baseFunctor{
public:
virtual void operator()()=0;
virtual baseFunctor Clone()=0;
};
This works, however obviously it restricts these functors to having an operator method that returns void and accepts no parameters. I need to be able to accept a functor in my class that can take any type of parameters and return anything. Its apparently do-able but I can't seem to find a way to do it. I have considered using templates, multiple inheritance, but I keep getting thwarted by the fact that the class that needs to run this functor must be able to accept any type, so will accept the base class type, and so will not know the actual type of the functor.
Any suggestions of what avenue to look at would be appreciated.
How will the class that calls the functor know what parameters to provide and what to do with the return value, if any?
So, if I'm reading this right, you have a "Visitor pattern." It might be a good thing for you to look up.
Someone needs to know what type the functor is to give it arguments. Often with functors, the arguments are assigned to fields of the derived class, and operator() will operate on those fields. That is, the dumb method that calls the functor and doesn't know anything about it is given the closure (method plus arguments all in one class) by someone more knowledgeable.
If you do want generic functors that take multiple arguments in the operator(), templating will get you partway there, but you'll need one per arity.
I agree with Neil. Your main class has to know what parameters to pass and what return value to expect from these functors. Can you just type-cast your "functor" to an appropriate class that supports the function with the necessary arguments and return value?
class baseFunctor
{
};
class functor1x2: public baseFunctor
{
public:
virtual void* execute(void*, void*);
}
class MainClass
{
public:
void Execute(baseFunctor* ipFunctor)
{
functor1x2* lpFunctor1x2 = dynamic_cast<functor1x2*>(ipFunctor);
if(lpFunctor1x2)
{
lpFunctor1x2->execute(NULL, NULL);
}
}
}
I'm not sure what could be accomplished with this approach that couldn't more easily be accomplished with the Visitor pattern, as Drew noted.
If you are open to using the Boost library (www.boost.org), you might find Boot.Bind and Boost.Function of particular interest. I have used them in the past to achieve something very much along the lines of what you are discussing.
If you use Boost.Bind, you can perform currying on the functors to account for differences between the number of arguments the functor expects and the number of arguments the Run method expects (i.e., zero). The code that creates the functor would have to bind any arguments to specific values and thus create a zero-argument functor that can be passed to Run().
MV
Why'd you want to return the functor? Are you storing some state as well? Some more detail will be much appreciated since it is not very clear what exactly you want to do.
If you plan to use inheritance, do look up Covariant Return Types (and the Virtual Constructor idiom).
Now, for the meat of the problem: the problem is really not with passing in a functor but with functor application. You may want to take a look at boost::lambda and boost::parameter as well.
I think you want an ellipsis argument, like varargs for C++.
Perhaps std::tr1::function is interesting for you?