I am trying to upgrade the mockito version in my project.
Current version: mockito-all [1.9.5]
Upgrade to : mockito-core [2.8.8]
Some of my old tests are failing with this issue
Test:
.andExpect(jsonPath("$.paymentTransaction.totalAmount").value(new GreaterThan<Double>(0.0D)))
Failure Message:
java.lang.AssertionError: For JSON path $.paymentTransaction.totalAmount type of value
Expected :class org.mockito.internal.matchers.GreaterThan
Actual :class java.lang.Double
Any clue, if this is to be handled in a different way with the mockito version upgrade ?
You ended up using the wrong overload:
public ResultMatcher value(Object expectedValue)
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/web/servlet/result/JsonPathResultMatchers.html#value-java.lang.Object-
Instead of
public <T> ResultMatcher value(Matcher<T> matcher)
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/web/servlet/result/JsonPathResultMatchers.html#value-org.hamcrest.Matcher-
The reason is you used matcher from Mockito, not from Hamcrest. You need to use:
org.hamcrest.Matchers.greaterThan(T value)
Also, note that there is an overload of jsonPath taking a Hamcrest matcher as a second argument (no need to call value)
Related
We run a set of tests in a CI pipeline and call our test classes like this:
java -classpath junit-jupiter-api-5.0.1.jar:junit-platform-console-standalone-1.0.1.jar org.junit.platform.console.ConsoleLauncher --select-class xy.Test
If class xy.Test cannot be found on the classpath an error message appears but ConsoleLauncher's return value is 0! Since our CI system runs unattended the return value is the only important return value!
As I have seen this behaviour got updated in JUnit 5.0.0 M2 but I regard this as I mistake: If I define a class by --select-class and the class cannot be found then something has gone wrong!
As I countermeasure I hacked (by means of introspection) org.junit.platform.commons.util.BlacklistedExceptions by overwriting blacklist's field with OutOfMemoryError (=default) and PreconditionViolationException (=case where class could not be found).
(If the standard behaviour shall not be changed...) I think there should be a better way to get this behaviour!
I updated an application JDK from 1.6 to 1.8 but I kept the language level 1.6 in IntelliJ.
After updating I got compilation error in some tests in assertThat statements with checking type of an object. The code is like this:
assertThat((Class) myList.get(0).getMyClassType(), is(equalTo(MySubclass.class)));
myList is looking like this:
List<MyClassDefinition> myList = myClassDefinition.getMyClassDefinitions(reader);
Where definition of MyClassDefinition and getMyClassType() are like this:
public class MyClassDefinition {
private Class<? extends MyClass> classType;
public Class<? extends MyClass> getMyClassType() {
return classType;
}
}
and MySubclass is Myclass's subclass:
public class MySubclass extends MyClass {
#Override
public void initialise() {
// some action here!
}
}
The definition of MyClass is
public abstract class MyClass extends AnotherClass<AnotherType>{
//Definitions
}
The import for Assert is and equals library is this:
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
and the hamcrest version is hamcrest-all-1-3
After changing project SDK to jdk 1.8 I am getting this error message:
Error:(136, 9) java: no suitable method found for assertThat(java.lang.Class,org.hamcrest.Matcher<java.lang.Class<MySubClass>>)
method org.hamcrest.MatcherAssert.assertThat(java.lang.String,boolean) is not applicable
(argument mismatch; java.lang.Class cannot be converted to java.lang.String)
method org.hamcrest.MatcherAssert.<T>assertThat(java.lang.String,T,org.hamcrest.Matcher<? super T>) is not applicable
(cannot infer type-variable(s) T
(actual and formal argument lists differ in length))
method org.hamcrest.MatcherAssert.<T>assertThat(T,org.hamcrest.Matcher<? super T>) is not applicable
(cannot infer type-variable(s) T
(argument mismatch; org.hamcrest.Matcher<java.lang.Class<MySubClass>> cannot be converted to org.hamcrest.Matcher<? super java.lang.Class>))
application is build with Ant and we have added hamcrest jar file to class file, so there is no change when we are altering JDK in project.
So my question is why this code is working with JDK 1.6 but not working with 1.8 while I am using same level of language (1.6) for compilation? Is it depend to different libraries some how?
Apparently, you had a problem with the generic type signatures which you worked around by inserting a type cast to the raw type Class, which causes the compiler to treat the entire statement as an unchecked operation using raw types only.
As you can see from the compiler message, org.hamcrest.Matcher<java.lang.Class<MySubClass>> cannot be converted to org.hamcrest.Matcher<? super java.lang.Class>, it now did a generic type check which (correctly) failed, but imho, it shouldn’t do that type check under Java 6 language rules. The problem stems from the fact that JDK8 doesn’t include the original Java 6 compiler but rather let the new compiler attempt to compile using the old rules, which may not be that precise.
But regardless of whether the behavior is correct or not, I wouldn’t expect a fix for it, as emulating the old Java 6 language rules is not of a high priority.
Note that with source level 1.8, the code compiles without problems, even without the raw type cast. The original problem stems from the restrictive signature of CoreMatchers.equalTo(…). The standalone expression equalTo(InstanceOfFoo) returns a Matcher<Foo>, which being passed to assertThat allows to only test instances of Foo (it’s even worse when using isA(Foo.class) which also can only test instances of Foo, which makes the test pointless).
With Java 8, there is target type inference, which allows, e.g.
Matcher<Object> m = equalTo(InstanceOfFoo);, which will infer Object for <T> and passes, as InstanceOfFoo is also assignable to Object. This also works in conjunction with the compound assertThat statement of your question, inferring a suitable type.
This guides us to the general solution that works with all language levels. Just use
assertThat(myList.get(0).getMyClassType(), is(equalTo((Object)MySubclass.class)));
Class<MySubclass> is, of course, assignable to Object which makes the cast a no-op. But then, getting a Matcher<Object>, you can check every object you like, including the result of myList.get(0).getMyClassType(), which is, of course, also assignable to Object. Unlike your original workaround, this doesn’t bear any raw type usage nor unchecked operation.
You could also use an explicit type instead of a cast, CoreMatchers.<Object>equalTo(MySubclass.class), but this eliminates the benefit of import static.
By the way, when matching Class objects, you may use sameInstance instead of equalTo.
I have the following piece of code:
PowerMockito.mockStatic(DateUtils.class);
//And this is the line which does the exception - notice it's a static function
PowerMockito.when(DateUtils.isEqualByDateTime (any(Date.class),any(Date.class)).thenReturn(false);
The class begins with:
#RunWith(PowerMockRunner.class)
#PrepareForTest({CM9DateUtils.class,DateUtils.class})
And I get org.Mockito.exceptions.InvalidUseOfMatchersException...... You cannot use argument matchers outside of verification or stubbing..... (The error appears twice in the Failure Trace - but both point to the same line)
In other places in my code the usage of when is done and it's working properly. Also, when debugging my code I found that any(Date.class) returns null.
I have tried the following solutions which I saw other people found useful, but for me it doesn't work:
Adding
#After
public void checkMockito() {
Mockito.validateMockitoUsage();
}
or
#RunWith(MockitoJUnitRunner.class)
or
#RunWith(PowerMockRunner.class)
Change to
PowerMockito.when(new Boolean(DateUtils.isEqualByDateTime(any(Date.class), any(Date.class)))).thenReturn(false);
Using anyObject() (it doesn't compile)
Using
notNull(Date.class) or (Date)notNull()
Replace
when(........).thenReturn(false);
with
Boolean falseBool=new Boolean(false);
and
when(.......).thenReturn(falseBool);
As detailed on the PowerMockito Getting Started Page, you'll need to use both the PowerMock runner as well as the #PrepareForTest annotation.
#RunWith(PowerMockRunner.class)
#PrepareForTest(DateUtils.class)
Ensure that you're using the #RunWith annotation that comes with JUnit 4, org.junit.runner.RunWith. Because it's always accepted a value attribute, it's pretty odd to me that you're receiving that error if you're using the correct RunWith type.
any(Date.class) is correct to return null: Rather than using a magic "matches any Date" instance, Mockito uses a hidden stack of matchers to track which matcher expressions correspond to matched arguments, and returns null for Objects (and 0 for integers, and false for booleans, and so forth).
So in the end,what worked for me was to export the line that does the exception to some other static function. I called it compareDates.
My implementation:
In the class that is tested (e.g - MyClass)
static boolean compareDates(Date date1, Date date2) {
return DateUtils.isEqualByDateTime (date1, date2);
}
and in the test class:
PowerMockito.mockStatic(MyClass.class);
PowerMockito.when(MyClass.compareDates(any(Date.class), any(Date.class))).thenReturn(false);
Unfortunately I can't say I fully understand why this solution works and the previous didn't.
maybe it has to do with the fact that DateUtils class is not my code, and I can't access it's source, only the generated .class file, but i'm really not sure about it.
EDIT
The above solution was just a workaround that did not solve the need to cover the DateUtils isEqualByDateTime call in the code.
What actually solved the real problem was to import the DateUtils class which has the actual implementation and not the one that just extends it, which was what I imported before.
After doing this I could use the original line
PowerMockito.mockStatic(DateUtils.class);
PowerMockito.when(DateUtils.isEqualByDateTime (any(Date.class),any(Date.class)).thenReturn(false);
without any exception.
I had a similar problem with TextUtils in my Kotlin Test Class
PowerMockito.`when`(TextUtils.isEmpty(Mockito.anyString())).thenReturn(true)
Resolved it by adding below code on top of my Test Class
#PrepareForTest(TextUtils::class)
and called mockStatic this before PowerMockito.`when`
PowerMockito.mockStatic(TextUtils::class.java)
I am writing a Java wrapper library around a ruby gem so I am embedding ruby within Java and not the other way around. I seem to be in the vast minority!
If I have a ruby method that returns a Time object then I can very easily convert it into a java.util.Date object on the Java side like this:
public Date getStartTime() {
IRubyObject result = RuntimeHelpers.invoke(runtime.getCurrentContext(),
this, "start_time");
return (Date) result.toJava(Date.class);
}
But I think I got lucky working this out by trial and error and not all like-seeming types can be converted in this way. I have another ruby method that returns a URI object (it could be a URI::HTTP or a URI::HTTPS in fact) but trying the obvious (given the above) conversion to a java.net.URI doesn't work (I also tried it with java.net.URL):
public URI getUri() {
IRubyObject result = RuntimeHelpers.invoke(runtime.getCurrentContext(),
this, "uri");
return (URI) result.toJava(URI.class);
}
This code compiles, but fails at run time:
Exception in thread "main" org.jruby.exceptions.RaiseException: (TypeError) cannot
convert instance of class org.jruby.RubyObject to class java.net.URI
I realise that in ruby a URI is actually a module and URI::HTTPS, etc are the classes, so I'm not entirely surprised that the above didn't work. But there's clearly a bit of internal "magic" being done for the Time/Date example so I was wondering if there were similar conversions provided for other types, which types and where they are documented.
Any pointers much appreciated.
https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby says "Conversion of Types – Ruby to Java – See the JRuby rspec source code dir spec/java_integration for many more examples. [examples, ...]".
Sure enough, coercion_spec.rb contains a lot of examples/specifications. Here's the case you already use:
describe "Time\"to_java" do
describe "when passed java.util.Date" do
it "coerces to java.util.Date" do
t = Time.now
d = t.to_java(java.util.Date)
d.class.should == java.util.Date
end
end
# [...]
end
I believe this is the best documentation currently available.
If I register a component with the container with a name (don't worry... contrived example!)
container.Register(Component.For<double>().Instance(Math.PI).Named("pi")
And ask to resolve that service type with a different name
container.Resolve<double>("e")
I get an ComponentNotFound exception. But now if I use the typed factory facility
interface IDoubleFactory { double GetDoubleByName(string name); }
container.Register(
Component.For<DoubleSelector, ITypedFactoryComponentSelector>()
Component.For<IDoubleFactory>().AsFactory(f => f.SelectedWith<DoubleSelector>())
Component.For<double>().Instance(Math.PI).Named("pi"))
public class DoubleSelector : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
return arguments[0] as string;
}
}
and try to use the factory to resolve a bogus name
container.Resolve().GetDoubleByName("e")
I get pi back instead of an exception. It appears that having given a name to the ITypedFactoryComponentSelector which did not help, it has fallen back to just using the Type (in this case double) and grabbed the first thing registered against it.
The answer may be a bug in Windsor 2.5.1. The contract for ITypedFactoryComponentSelector suggests that if you return null for ComponentType but non-null for ComponentName, the lookup will be done by name, and not type. But two problems get in your way if you try to do that.
According to GitHub sources, code in DefaultTypedFactoryComponentSelector.BuildFactoryComponent calls GetCompatibleArrayItemType on what may be a null ComponentType pointer, which causes an exception. This seems like a bug, plain and simple.
If you find a way to monkey patch that, then it appears that TypedFactoryComponentResolver.Resolve method doesn't quite arrange to call the right overloads on the kernel to resolve in cases where ComponentType is null. I'm much less clear whether this is a bug or a lack in my understanding of which IWindsorContainer.Resolve methods do what. That said, a dispatch to the various methods (Resolve<object>(string key), for example) seems to do the trick.
Both classes are unsealed, so it's straightforward to fix with derived classes.