Mockito: using when over a mocked Mono with timeout method causes InvalidUseOfMatchersException - mockito

I am working on the unit test of a reactive WebClient usage and my problem comes when I try to mock the behavior of Mono with the method timeout(Duration d).
I just want to control the result of a call like:
private Mono<String> withTimeout(Mono<String> myMono) {
return myMono.timeout(Duration.of(globalDuration));
}
So I am using this:
#Test
void test() {
...
Mono<String> monoMock = (Mono<String>) Mockito.mock(Mono.class);
when(monoMock.timeout(Mockito.any(Duration.class))).thenReturn(Mono.just("OK"));
...
}
But it generates a
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaces or misused argument matcher detected here:
-> at service.UserServiceTest.test(UserServiceTest.java:98)
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
verify(mock).someMethod(contains("foo"))
This message may appear after an NullPointerException if the last matcher is retur....
How should I actually when the result of this Mono.timeout method?

I also just experienced this strange error, in addition to your error I also got java.lang.NullPointerException.
I was able to solve this by importing:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.8.1</version>
</dependency>
After this I was able to simply do this without any issues:
var monoMock = Mockito.mock(Mono.class);
lenient().when(monoMock.timeout((any(Duration.class)))).thenReturn(monoMock);

Related

ServiceStack with MiniProfiler for .Net 6

I was attempting to add Profiling into ServiceStack 6 with .Net 6 and using the .Net Framework MiniProfiler Plugin code as a starting point.
I noticed that ServiceStack still has Profiler.Current.Step("Step Name") in the Handlers, AutoQueryFeature and others.
What is currently causing me some stress is the following:
In ServiceStackHandlerBase.GetResponseAsync(IRequest httpReq, object request) the Async Task is not awaited. This causes the step to be disposed of the when it reaches the first async method it must await, causing all the subsequent nested steps to not be children. Is there something simple I'm missing here or is this just a bug in a seldom used feature?
In SqlServerOrmLiteDialectProvider most of the async methods make use of an Unwrap function that drills down to the SqlConnection or SqlCommand this causes an issue when attempting to wrap a command to enable profiling as it ignores the override methods in the wrapper in favour of the IHasDbCommand.DbCommand nested within. Not using IHasDbCommand on the wrapping command makes it attempt to use wrapping command but hits a snag because of the forced cast to SqlCommand. Is there an easy way to combat this issue, or do I have to extend each OrmliteDialectProvider I wish to use that has this issue to take into account the wrapping command if it is present?
Any input would be appreciated.
Thanks.
Extra Information Point 1
Below is the code from ServiceStackHandlerBase that appears (to me) to be a bug?
public virtual Task<object> GetResponseAsync(IRequest httpReq, object request)
{
using (Profiler.Current.Step("Execute " + GetType().Name + " Service"))
{
return appHost.ServiceController.ExecuteAsync(request, httpReq);
}
}
I made a small example that shows what I am looking at:
using System;
using System.Threading.Tasks;
public class Program
{
public static async Task<int> Main(string[] args)
{
Console.WriteLine("App Start.");
await GetResponseAsync();
Console.WriteLine("App End.");
return 0;
}
// Async method with a using and non-awaited task.
private static Task GetResponseAsync()
{
using(new Test())
{
return AdditionAsync();
}
}
// Placeholder async method.
private static async Task AdditionAsync()
{
Console.WriteLine("Async Task Started.");
await Task.Delay(2000);
Console.WriteLine("Async Task Complete.");
}
}
public class Test : IDisposable
{
public Test()
{
Console.WriteLine("Disposable instance created.");
}
public void Dispose()
{
Console.WriteLine("Disposable instance disposed.");
}
}
My Desired Result:
App Start.
Disposable instance created.
Async Task Started.
Async Task Complete.
Disposable instance disposed.
App End.
My Actual Result:
App Start.
Disposable instance created.
Async Task Started.
Disposable instance disposed.
Async Task Complete.
App End.
This to me shows that even though the task is awaited at a later point in the code, the using has already disposed of the contained object.
Mini Profiler was coupled to System.Web so isn't supported in ServiceStack .NET6.
To view the generated SQL you can use a BeforeExecFilter to inspect the IDbCommand before it's executed.
This is what PrintSql() uses to write all generated SQL to the console:
OrmLiteUtils.PrintSql();
Note: when you return a non-awaited task it just means it doesn't get awaited at that point, it still gets executed when the return task is eventually awaited.
To avoid the explicit casting you should be able to override a SQL Server Dialect Provider where you'll be able to replace the existing implementation with your own.

wiremock-groovy library syntax

I use library https://github.com/tomjankes/wiremock-groovy for WireMock in Spock tests.
My big concern is that Intellij Idea doesn't understand syntax and so do I.
Exmaple from documentation:
wireMockStub.stub {
request {
method "GET"
url "/some/thing"
}
response {
status 200
body "Some body"
headers {
"Content-Type" "text/plain"
}
}
}
As far as I understand, stub { ... } is a method call with lambda as an argument. That's ok, going further.
request {...} is a method call with two arguments: method and url. Is it correct? Idea points to the static method of the class WireMock, but I'm in doubts, because pointed method has second arg named urlPattern, not just url.
Then we see something similar with response. Idea doesn't recognize it at all, so no hints, no syntax check and so on.
So, there are two main questions:
- What is this syntax?
- How to force idea to understand it?
stub { ... } is a method call with lambda as an argument.
Correct, but the {...} is a Closure, not lambda.
request {...} is a method call with two arguments: method and url. Is it correct?
No, both method and url are method calls. In Groovy parenthesis can be omitted for clarity, so for java developers the block can be rewritten as:
request( {
method( "GET" )
url( "/some/thing" )
} )
or
request(){
...
}
The whole thing is made possible by Groovy DSL support, which may not always be properly recognized be IDEs during compile time, but runs smoothly nevertheless.

UndeliverableException while calling onError of ObservableEmitter in RXjava2

I have a method which creates an emitter like below, there are a problem(maybe it is normal behavior) with calling onError in retrofit callback. I got UndeliverableException when try to call onError.
I can solve this by checking subscriber.isDiposed() by I wonder how can call onError coz i need to notify my UI level.
Addition 1
--> RxJava2CallAdapterFactoryalready implemented
private static Retrofit.Builder builderSwift = new Retrofit.Builder()
.baseUrl(URL_SWIFT)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(new ToStringConverterFactory());
--> When i added below code to application class app won't crash
--> but i get java.lang.exception instead of my custom exception
RxJavaPlugins.setErrorHandler(Functions<Throwable>emptyConsumer());
#Override
public void onFileUploadError(Throwable e) {
Log.d(TAG, "onFileUploadError: " + e.getMessage());
}
public Observable<UploadResponseBean> upload(final UploadRequestBean uploadRequestBean, final File file) {
return Observable.create(new ObservableOnSubscribe<UploadResponseBean>() {
#Override
public void subscribe(#NonNull final ObservableEmitter<UploadResponseBean> subscriber) throws Exception {
// ---> There are no problem with subscriber while calling onError
// ---> Retrofit2 service request
ftsService.upload(token, uploadRequestBean, body).enqueue(new Callback<UploadResponseBean>() {
#Override
public void onResponse(Call<UploadResponseBean> call, Response<UploadResponseBean> response) {
if (response.code() == 200){
// ---> calling onNext works properly
subscriber.onNext(new UploadResponseBean(response.body().getUrl()));
}
else{
// ---> calling onError throws UndeliverableException
subscriber.onError(new NetworkConnectionException(response.message()));
}
}
#Override
public void onFailure(Call call, Throwable t) {
subscriber.onError(new NetworkConnectionException(t.getMessage()));
}
});
}
});
}
Since version 2.1.1 tryOnError is available:
The emitter API (such as FlowableEmitter, SingleEmitter, etc.) now
features a new method, tryOnError that tries to emit the Throwable if
the sequence is not cancelled/disposed. Unlike the regular onError, if
the downstream is no longer willing to accept events, the method
returns false and doesn't signal an UndeliverableException.
https://github.com/ReactiveX/RxJava/blob/2.x/CHANGES.md
The problem is like you say you need to check if Subscriber is already disposed, that's because RxJava2 is more strict regarding errors that been thrown after Subscriber already disposed.
RxJava2 deliver this kind of error to RxJavaPlugins.onError that by default print to stack trace and calls to thread uncaught exception handler. you can read full explanation here.
Now what's happens here, is that you probably unsubscribed (dispose) from this Observable before query was done and error delivered and as such - you get the UndeliverableException.
I wonder how can call onError coz i need to notify my UI level.
as this is happened after your UI been unsubscribed the UI shouldn't care. in normal flow this error should delivered properly.
Some general points regarding your implementation:
the same issue will happen at the onError in case you've been unsubscribed before.
there is no cancellation logic here (that's what causing this problem) so request continue even if Subscriber unsubscribed.
even if you'll implement this logic (using ObservableEmitter.setCancellable() / setDisposable()) you will still encounter this problem in case you will unsubscribe before request is done - this will cause cancellation and your onFailure logic will call onError() and the same issue will happen.
as you performing an async call via Retrofit the specified subscription Scheduler will not make the actual request happen on the Scheduler thread but just the subscription. you can use Observable.fromCallable and Retrofit blocking call execute to gain more control over the actual thread call is happened.
to sum it up -
guarding calls to onError() with ObservableEmitter.isDiposed() is a good practice in this case.
But I think the best practice is to use Retrofit RxJava call adapter, so you'll get wrapped Observable that doing the Retrofit call and already have all this considerations.
I found out that this issue was caused by using incorrect context when retrieving view model in Fragment:
ViewModelProviders.of(requireActivity(), myViewModelFactory).get(MyViewModel.class);
Because of this, the view model lived in context of activity instead of fragment. Changing it to following code fixed the problem.
ViewModelProviders.of(this, myViewModelFactory).get(MyViewModel.class);

Passing pointers to async as arguments generates compiler error

I'm trying to get my head around async but have not yet found a way to pass pointers. The aim is to pass a pointer to a pointer so that the thread readTable initialises the pointer to a PostgreSQL connection as shown below.
PGconn *conn = NULL;
future<int> resultFuture;
void init
{
resultFuture = async(launch::async, readTable(&conn));
}
However the compiler complains with:
error: no matching function for call to ‘async(std::launch, int)'
Is passing pointers like this not allowed with async?
Thanks for any help.
I guess
void init
{
resultFuture = async(launch::async, readTable,&conn);
}
the second parameters is a Callable (which is a function to pointer, or an object with overloaded operator() or a lambda function). all the rest are the argument to pass into the callable.
please read std::async documentation here:
http://en.cppreference.com/w/cpp/thread/async
and about perfect forwarding here :
Advantages of using forward

EasyMock AssertionError when invoking Logger.error(String, Throwable)

I am seeing assertion error when I include a Throwable while invoking Log4j.error method. I do have Logger.class, PrintWriter.class, AuthenticationException.class in the #PreparateForTest block. I do not see the error if I do not pass the Throwable as an argument.
What am I missing in setting up mocks correctly?
Caused by: java.lang.AssertionError:
Unexpected method call AuthenticationException.printStackTrace(java.io.PrintWriter#2c64e8ad):
at org.junit.Assert.fail(Assert.java:93)
at com.xxx.yy.security.client.ClientTest.authenticateFail(ClientTest.java:282)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
... 23 more
JUnit test code snippet is as below:
AuthenticationException mockAuthException = PowerMock
.createMock(AuthenticationException.class);
PrintWriter mockPrintWriter = PowerMock
.createMock(PrintWriter.class);
Logger mockLogger = PowerMock.createMock(Logger.class);
String message = "blah";
mockLogger.error(message, mockAuthException);
EasyMock.expectLastCall();
mockAuthException.printStackTrace(mockPrintWriter);
EasyMock.expectLastCall();
Code snippet that is causing the issue is as below:
try{
.
.
}catch (AuthenticationException ex) {
LOGGER.error("SOME MESSAGE HERE", ex);
throw ex;
}
you are getting an Unexpected method call error which can be solved as follows:
AuthenticationException mockAuthException = EasyMock.createNiceMock(AuthenticationException.class);
PrintWriter mockPrintWriter = EasyMock.createNiceMock(PrintWriter.class);
Logger mockLogger = EasyMock.createNiceMock(Logger.class);
String message = "blah";
mockLogger.error(message, mockAuthException);
EasyMock.expectLastCall();
mockAuthException.printStackTrace(mockPrintWriter);
EasyMock.expectLastCall();
The changes over here are using easymock instead of powermock,and creating a niceMock instead of normal mock.
The createMock(..) method is strict and can not identify if a method is internally called or not,but when you use createNiceMock(..) this check is ignored and you do not get a UnexpectedMethodCall error
Hope it helps!
Good luck!
LOGGER.error("SOME MESSAGE HERE", ex);
This line appears to be calling the printStacktrace method of the ex, i.e the AuthenticationException type. Since you've mocked it, you have to tell the behavior the object (the mock, technically) should behave in, when this call is encountered.
You have 3 choices, apart from relaxing the verification of course thru the use of nice mocks, assuming you really expect this exception to be thrown (your question is a bit vague about it):
See if you can expect the LOGGER.error("SOME MESSAGE HERE", ex);, i.e mock the LOGGER. The LOGGER appears to be a static variable, but you seem to be using Powermock, so I don't think you'll have any problems mocking it, but if you do have concerns mocking the LOGGER, read on
Tell Easymock how it's supposed to respond when it encounters the printStacktrace method call on the mock object mockAuthException by placing an expectation on it like this (printStacktrace being a void method) before you replay the mock:
mockAuthException.printStacktrace(); expectLastCall().andDoSomethingIfNeeded();
Don't mock the AuthenticationException type at all unless it's absolutely necessary - it does look like you can do without mocking it, say, by creating a Stub of the type.

Resources