Can I mix one matcher and 1 exact value in mockito arguments - mockito

If I create a mock like this
when(servicesTestEnv.mockUserProfileAndPortfolioTransactionRepository.get(servicesTestEnv.mockDistributedTransaction,ArgumentMatchers.any[ExternalUserProfileKeys]))
.thenReturn(Right(servicesTestEnv.externalUserProfile))
I get error
Invalid use of argument matchers! 2 matchers expected, 1 recorded: -> at UnitSpecs.ServiceSpecs.UserTransactionDatabaseServiceSpecs.$anonfun$new$17(UserTransactionDatabaseServiceSpecs.scala:170)
But if I replace both with value
when(servicesTestEnv.mockUserProfileAndPortfolioTransactionRepository.get(servicesTestEnv.mockDistributedTransaction,keys))
.thenReturn(Right(servicesTestEnv.externalUserProfile))
or
when(servicesTestEnv.mockUserProfileAndPortfolioTransactionRepository.get(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[ExternalUserProfileKeys]))
.thenReturn(Right(servicesTestEnv.externalUserProfile))
then I don't get the error
Is this a rule in Mockito that all argument either need to matchers or values?

Mixing of matchers and raw values is not supported by Mockito at the moment and mocking has to be done fully one way (matchers) or the other (concrete values), just like you've shown in your question.
There's a discussion on Mockito GitHub page regarding mixed argument mocking, but it's been pretty much dead for two years.

Related

How to use negative expression in Cucumber Java

In Cucumber you can write Then expressions and their step definitions to verify the results. The problem is I don't want to write 2 different step definitions for checking the outcome. One example would be like this:
Then the transaction is successful
and
Then the transaction is not successful
How can I get around this?
I've found out that in Ruby you could consolidate step definitions by using capturing optional groups as described [here]. That is:
Then /^I should( not)? see the following columns: "([^"]*)"$/ do |negate, columns|
within('table thead tr') do
columns.split(', ').each do |column|
negate ? page.should_not(have_content(column)) : page.should(have_content(column))
end
end
end
But I don't know whether this is possible in Java or not. And even if it is what type of variable should I be capturing?
Why not write two step definitions. Each one is simpler, on topic, doesn't require a regex. If you delegate the work the step definitions do to a helper method you can remove almost all of the code duplication as well
Then I should see the following columns |cols|
should_see_cols(cols)
end
Then I should not see the following columns |cols|
should_not_see_cols(cols)
end
Now you have super simple crystal clear step definitions and you can write your method/ methods however you want.
Step definition duplication is irrelevant if all your step definitions just make a single call to a helper method. You can be as DRY as you like with your helper methods and still keep your scenarios super simple and remove the need to use regex's and complex logic in your step defs.
In Java, I would create one method with capture groups (is|is not), and derive a boolean from that which I would compare to the value. On the other hand, this adds logic to your test implementation so there is something to be said for #diabolist's solution of having 2 distinct step definitions.

How to verify kotlin varargs function using mockito

I have a kotlin function of this form in an interface:
fun foo(bar: String, vararg baz: Pair<String, ByteArray>):Boolean
Using Mockito to mock this interface, how do I verify that this function was called with no Pairs?
It doesn't work leaving the second matcher off, because then Mockito complains that it needs two matchers.
Using any any*() matcher, including anyVararg(), fails because of typing.
A non-answer to give some inspiration:
Keep in mind that Mockito doesn't know or care what you are writing in some Kotlin source code file.
Mockito only deals with the compiled byte code. In other words: Mockito looks into the final classfile; created by the kotlin compiler.
Thus: your first stop should be javap to disassemble the class file that contains that method definition. You check the signature of the method there; and that should tell you how to specify correct argument matchers to Mockito.
And just another idea: java varargs translate arrays. So "no" args means: an empty array. So you probably want to match specifically on something like empty array of Pairs.

Groovy can use a subscript on an XSSFSheet in the simple console, but in IntelliJ it can't

I have a variable of this type:XSSFSheet sheet (I'm using apache-poi to read from Excel).
In the simple groovy console I can do sheet[4][5] to access a certain cell by coordinates. When I try the same thing in IntelliJ, it gives me the exception that
No signature of method: org.apache.poi.xssf.usermodel.XSSFSheet.getAt() is applicable for argument types: (java.lang.Integer) values: [0]
Possible solutions: getAt(java.lang.String), getRow(int), putAt(java.lang.String, java.lang.Object), wait(), last(), first()
I looked in the reference and indeed, XSSFSheet can't be indexed by an int. But why then it is possible in the simple groovy console that comes with it? Can I do the same in IntelliJ?
This is old, and I'm only answering because I was wondering the same thing you asked in your last comment and found the answer trying to understand.
As you mention in your last comment, the subscript operator in groovy translates to the getAt() method, and as you say, the XSSFSheet class doesn't have such a method in java.
Since it can indeed be called from groovy, it does exist somewhere. With a bit of metaprogramming, we get the following:
def getAt = org.apache.poi.xssf.usermodel.XSSFRow.metaClass.getMetaMethod("getAt", [java.lang.Integer] as Class[])
println getAt
org.codehaus.groovy.runtime.dgm$240#e7edb54[name: getAt params: [int] returns: class java.lang.Object owner: interface java.lang.Iterable]
Which means it comes from the Iterable interface. And still, this is not true in java. But groovy adds many methods to standard java classes, and indeed we can see here that it adds a getAt() method to Iterable.
This doesn't answer your original question (why doesn't it work in your IntelliJ ? it should and it does here), but it answers a question in the comments. I would have posted it there, but I lack reputation.

Using mockito.verify to ignore one of the parameters

I want to skip checking one of the parameters in a verify call. So for:
def allowMockitoVerify=Mockito.verify(msg,atLeastOnce()).handle(1st param,,3rd param)
I want to skip checking for the second parameter. How can I do that?
Unfortunately Mockito wont allow you to mix and match raw values and matchers (e.g. String and Matchers.any())
However you can use the eq() Matcher to match against a specific value, for example
Mockito.verify(msg, atLeastOnce())
.handle(eq("someValue"), any(Thing.class), eq("anotherValue"));
Thanks to this post for a good example of this
Mockito: InvalidUseOfMatchersException
You can try Mockito.any(), which basically means we are not interested in this parameter.
I'm using Mockito 3.9.0 and because you cannot mix matchers with expected values, i.e, you can't verify that the first argument is a specific string like test-profile and the second is anything, so you need to convert all to matchers, so you can't do something like:
verify(userAuthorizationService).authorizeRequest("test-profile", any());
Instead, you need to convert values into matchers, like:
verify(userAuthorizationService).authorizeRequest(matches("test-profile"), any());
Note the matches and any are static imports from org.mockito.ArgumentMatchers

JUnit AssertSame fails on object.toString in groovy

I am trying to test the overridden toString() in groovy (I know it is trivial but that is what you get after reading kent beck's TDD book).
I assertSame on the expected string and the actual
Here is the code block:
#Test void testToString(){
def study = new Study(identifier:"default-study", OID:"S_DEFAULTS1", name:"Default Study")
def expected = "org.foo.oc.model.bar(OID:S_DEFAULTS1, name:Default Study, identifier:default-study)"
assertSame "Should be equal", expected, study.toString()
}
Here is the stack trace for the failed test:
junit.framework.AssertionFailedError: Should be equal expected same:org.foo.oc.model.bar(OID:S_DEFAULTS1, name:Default Study, identifier:default-study) was not:org.foo.oc.model.bar(OID:S_DEFAULTS1, name:Default Study, identifier:default-study)
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.failNotSame(Assert.java:273)
at junit.framework.Assert.assertSame(Assert.java:236)
Just to add that assertEquals works well with the same parameters.
I know it is no biggie but I want to understand why it fails.
Thanks
Why aren't you using assertEquals which uses .equals()? assertSame compares object references (== operator). Even though the strings are the same, they are two different objects, hence the assertion is failing.
UPDATE: This is a very common mistake in Java: String.equals() and == operator work differently. This has been discussed several times:
How do I compare strings in Java?
Java String.equals versus ==
Difference between Equals/equals and == operator?
I know you are using Groovy which does not suffer this problem, but JUnit is written in Java and behaves according to the rules above.
UPDATE: actually, your string are different:
org.foo.oc.model.bar(OID:S_DEFAULTS1, name:Default Study, identifier:default-study)
org.foo.oc.model.bar(OID:S_DEFAULTS1, name:Default Study, identifier:default-study)
Your original uses lowercase d in "default Study" but your expected string does not.
EDIT: when comparing strings you should always use equals() rather than comparing references. Two strings that pass the equals() test may or may not also be the same object.
BTW, in Groovy == is the same as equals().

Resources