Mockito throws error with Kotlin when verifying with argument matchers or captors - kotlin

When using Mockito with Kotlin, if I try to verify Mock calls, it work fine like (this is in a Spring test):
#MockBean
lateinit var fragmentProcessor: FragmentProcessor
verify(fragmentProcessor, timeout(20000)).processFragment(expectedFragment)
that gives the expected behaviour... but just doing something like:
verify(fragmentProcessor, timeout(20000)).processFragment(Mockito.eq(expectedFragment))
will give the following error:
Missing method call for verify(mock) here:
-> at uk.co.argos.productapi.services.kafka.KafkaConsumerServiceTest.testFragmentProcessorReceivesMessages(KafkaConsumerServiceTest.kt:47)
Example of correct verification:
verify(mock).doSomething()
Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
the same happens with ArgumentCaptor or other matchers

Are you sure that you call fragmentProcessor.processFragment(expectedFragment) somewhere in your code before verify times out?
Error message says that you don't, so verify throws an exception (as it should do).
In this line:
verify(fragmentProcessor, timeout(20000)).processFragment(expectedFragment)
You don't use verify correctly (you have to use Mockito.eq): it doesn't verify anything so doesn't throw, but it doesn't mean that it works as you suppose.

Related

How to use `Which` in FluentAssertions?

I'm using fluent assertions and I have this test:
result.Should().NotBeNull();
result.Link.Should().Equals("https://someinvoiceurl.com");
which works fine but when I try this
result.Should().NotBeNull().Which.Link.Equals("https://someinvoiceurl.com");
I got this error
'AndConstraint<ObjectAssertions>' does not contain a definition for 'Which' and no accessible extension method 'Which' accepting a first argument of type 'AndConstraint<ObjectAssertions>' could be found (are you missing a using directive or an assembly reference?)
What I'm doing wrong?
The problem here is that .NotBeNull() is not generic (it is an extension on ObjectAssertions rather than GenericObjectAssertions), so it can't chain the type information to later calls.
I think this is a flaw in the library design, personally, but it is easily worked around by substituting .NotBeNull() with .BeOfType<T>() as so:
result.Should().BeOfType<ThingWithLink>() // assertion fails if `result` is null
.Which.Link.Should().Be("https://someinvoiceurl.com");
Of course, if you assert on your ThingWithLink type a lot, it could be worth writing a custom assertion so that you can be "more fluent":
result.Should().BeOfType<ThingWithLink>()
.And.HaveLink("https://someinvoiceurl.com");
If you need something more ad-hoc, you can always just use .BeEquivalentTo() to do structural comparison:
result.Should().NotBeNull()
.And.BeEquivalentTo(new { Link = "https://someinvoiceurl.com" }); // ignores all members on `result` except for `result.Link`

How do I use MethodCall.invoke(someElementMatcher) to create a MethodCall representing a method I subsequently define in an instrumented type?

I am using ByteBuddy to generate a class.
Prior to working with DynamicType.Builder, I was going to store a MethodCall as an instance variable:
private final MethodCall frobCall =
MethodCall.invoke(ElementMatchers.named("frob")); // here I invoke a method I'm going to define as part of the instrumented type
Then later in my generation logic for the instrumented type I define the frob method to do something:
.defineMethod("frob")
.intercept(...etc....) // here I define frob to do something
…and I define the (let's say) baz method to invoke frob:
.defineMethod("baz")
.withParameter(...) // etc.
.intercept(frobCall); // invokes "frob", which I've just defined above
(I am trying to keep this simple and may have mistyped something but I hope you can see the gist of what I'm trying to do.)
When I make() my DynamicType, I receive an error that indicates that the dynamic type does not define frob. This is mystifying to me, because of course I have defined it, as you can see above.
Is there some restriction I am unaware of that prohibits ElementMatchers from identifying instrumented type methods that are defined later? Do I really have to use MethodDescription.Latent here?
It should match all methods of the instrumented type. If this is not happening as expected, please set a breakpoint in MethodCall.MethodLocator.ForElementMatcher to see why the method is not showing up. I assume it is filtered by your method matcher.
I noticed however that it did not include private methods which is now fixed and will be released within Byte Buddy 1.10.18.

Does PHP 7 have a way to crash on non-existing class when using the `MyClass::class` notation?

A basic use case would be calling MyEventListener::class without having imported use MyNamespace\MyEventListener. The result would be a broken piece of code that's relatively hard to debug.
Does PHP 7 provide a directive to crash instead of returning the class name if no class exists? For example:
After calling use Foo\Bar;, Bar::class would return 'Foo\Bar'.
But if no import statement, PHP returns 'Bar', even though the class doesn't exist, not even in the global namespace.
Can I make it crash somehow?
The thing you need to keep in mind is that use Foo\Bar; is not "importing" anything. It is telling the compiler: when I say "Bar" I mean Bar from the namespace Foo.
Bar::class is substituted blindly with the string "Foo\Bar". It isn't checking anything.
Until you attempt to instantiate or interact with a class it will not check to see if it exists. That said, it does not throw an Exception, it throws an Error:
// this doesn't exist!
use Foo/Bar;
try {
$instanceOfBar = new Bar();
}
catch (Error $e) {
// catching an Exception will not work
// Throwable or Error will work
}
You can trap and check for non-existent classes at run time, but until you do it will happily toss around strings referring to classes that don't exist.
This is a blessing in the case of Laravel's IoC container and autoloader that abuses this to alias classes as convenient top-level objects. A curse, if you were expecting PHP to throw a fuss on ::class not existing.
Update:
My suggestion for anyone worried about this problem is to use PHPStan in your testing pipeline. It prevents a lot of mistakes, and unlike php -l it will catch if you were to try and interact with a non-existent class.
As far as I know you're going to get a nice error message when you try to instantiate a class that cannot be found through autoloading or explicitly added.
If you want to check if the class exists, first, try this:
$classOutsideNamespaceExists = class_exists('Bar');
$classInsideNameSpaceExists = class_exists('\\Foo\\Bar'));
Or you could try this syntax available since PHP 5.5:
class_exists(MyClass::class)
Finally, you can always use the tried and true method of a try-catch block.
try {
$instanceOfMyClass = new MyClass();
}
catch (Exception $e) {
// conclude the class does not exist and handle accordingly
}
PhpStorm proposes and generates hints like ArrayShape, Pure, etc.
But automatically it is adding
php use JetBrains\PhpStorm\ArrayShape;
or another.
Is not that dangerous that on some production server I will get error
'Class JetBrains\PhpStorm\ArrayShape not found'?
(c)LazyOne:
Well, just use composer require --dev jetbrains/phpstorm-attributes to add such classes to your project. See github.com/JetBrains/phpstorm-attributes
As long as instance of such a class is not actually gets instantiated (created) you should have no error because use statement is just a declaration.

How to properly cast this class for OCMockito?

I'm using OCMockito to mock some objects in my tests.
When I use verify I receive an error from Xcode:
Multiple methods named '.....' found with mismatched result, parameter type or attributes
In the readme of the project i found this note:
(If Xcode complains about multiple methods with the same name, cast verify to the mocked class.)
This is my original implementation:
__strong Class mockAdjustClass = mockClass([Adjust class]);
[verify(mockAdjustClass) trackEvent:hasProperty(#"callbackParameters", hasEntry(#"duration", isNot(#"0")))];
I tried to cast in different ways but i cannot get rid of the error, for example:
[verify(([Adjust class])mockAdjustClass) trackEvent:hasProperty(#"callbackParameters", hasEntry(#"duration", isNot(#"0")))];
[([Adjust class])verify(mockAdjustClass) trackEvent:hasProperty(#"callbackParameters", hasEntry(#"duration", isNot(#"0")))];
I found the solution and was very easy :(
[(Adjust *)verify(mockAdjustClass) trackEvent:hasProperty(#"callbackParameters", hasEntry(#"duration", isNot(#"0")))];

Equivalent of never(mock) in JMockit

I'm migrating some test cases from JMock to JMockit. It's been a pleasant journey so far but there's one feature from JMock that I'm not able to find in JMockit (version 0.999.17)
I want to check that a mock is never called (any method).
With JMock, all I needed is the following in my Expectations block:
never(mock)
Is it feasible somehow with JMockit?
EDIT:
I might have found a solution but it's not very explicit.
If I put any method of this mock with times =0 in my Expectations block then this mock becomes strict and I believe any method called would trigger an exception.
Try an empty full verification block, it should verify that no invocations occurred on any given mocks:
#Test
public void someTest(#Mocked SomeType mock)
{
// Record expectations on other mocked types...
// Exercise the tested code...
new FullVerifications(mock) {};
}