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

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.

Related

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

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);

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);

Multithreading code testing by Spock

I want to verify exception throwing in one of my running threads. This is piece of my test code:
then:
def e = thrown(RequestFormatException)
e.message == "Incorrect first line: INCORRECT LINE"
When I run this I get next messages:
Exception in thread "Thread-1" by.westside.staircase.core.exception.RequestFormatException: Incorrect first line: INCORRECT LINE
at by.westside.staircase.core.util.HttpUtil.parseHttpRequest(HttpUtil.kt:19)
at by.westside.staircase.core.server.ServerThread.run(ServerThread.kt:26)
at java.lang.Thread.run(Thread.java:745)
Expected exception of type 'by.westside.staircase.core.exception.RequestFormatException', but no exception was thrown
at org.spockframework.lang.SpecInternals.checkExceptionThrown(SpecInternals.java:79)
at org.spockframework.lang.SpecInternals.thrownImpl(SpecInternals.java:66)
at by.westside.staircase.core.server.SyncServerSpec.should throw exception in incorrect first line case(SyncServerSpec.groovy:26)
Spock, like JUnit, can only assert on exceptions thrown from the thread executing the test, not "any thread in the application". Your exceptions are not caught by spock, and can't be asserted.
You can play with Thread.uncaughtExceptionHandler but you should probably unit-test the runnable executed in your thread - or implement some error handling in your business logic, and test this part of the code.
I think another option is to actually catch the exception in your test case and assert on that. here is a snippet of my code (written in Groovy Spock):
def exceptionThrown = false
def exceptionMessage
def thread = new Thread( {_ ->
try{
//code you are testing
} catch(Exception e) { // change this to the exception you want to catch
exceptionThrown = true
exceptionMessage = e.getMessage()
}
})
then: "the right exception should be thrown"
exceptionThrown
exceptionMessage = "I am thrown" //this should be your error message
I ran into the same issue and took a simple, hokey route. In the spirit of "good software is testable software" I added a flag and asserted on that, labeling it: // only for testing. Which, of course, will be ignored down the road.
thrown(RequestFormatException)
this should be in your first line after then: as this is the constraint imposed by spock.
Whenever thrown or notThrown is called in it should be the first statement.
Note: thrown and notThrown both return true and hence there should be no comparison operator as well.
Hence, In your case , it should be like below:
then:
thrown(RequestFormatException)

Fail early vs. robust methods

I'm constantly (since years) wondering the most senseful way to implement the following (it's kind of paradoxic for me):
Imagine a function:
DoSomethingWith(value)
{
if (value == null) { // Robust: Check parameter(s) first
throw new ArgumentNullException(value);
}
// Some code ...
}
It's called like:
SomeFunction()
{
if (value == null) { // Fail early
InformUser();
return;
}
DoSomethingWith(value);
}
But, to catch the ArgumentNullException, should I do:
SomeFunction()
{
if (value == null) { // Fail early
InformUser();
return;
}
try { // If throwing an Exception, why not *not* check for it (even if you checked already)?
DoSomethingWith(value);
} catch (ArgumentNullException) {
InformUser();
return;
}
}
or just:
SomeFunction()
{
try { // No fail early anymore IMHO, because you could fail before calling DoSomethingWith(value)
DoSomethingWith(value);
} catch (ArgumentNullException) {
InformUser();
return;
}
}
?
This is a very general question and the right solution depends on the specific code and architecture.
Generally regarding error handling
The main focus should be to catch the exception on the level where you can handle it.
Handling the exceptions at the right place makes the code robust, so the exception doesn't make the application fail and the exception can be handled accordingly.
Failing early makes the application robust, because this helps avoiding inconsistent states.
This also means that there should be a more general try catch block at the root of the execution to catch any non fatal application error which couldn't be handled. Which often means that you as a programmer didn't think of this error source. Later you can extend your code to also handle this error. But the execution root shouldn't be the only place where you think of exception handling.
Your example
In your example regarding ArgumentNullException:
Yes, you should fail early. Whenever your method is invoked with an invalid null argument, you should throw this exception.
But you should never catch this exception, cause it should be possible to avoid it. See this post related to the topic: If catching null pointer exception is not a good practice, is catching exception a good one?
If you are working with user input or input from other systems, then you should validate the input. E.g. you can display validation error on the UI after null checking without throwing an exception. It is always a critical part of error handling how to show the issues to users, so define a proper strategy for your application. You should try to avoid throwing exceptions in the expected program execution flow. See this article: https://msdn.microsoft.com/en-us/library/ms173163.aspx
See general thoughts about exception handling below:
Handling exceptions in your method
If an exception is thrown in the DoSomethingWith method and you can handle it and continue the flow of execution without any issue, then of course you should do those.
This is a pseudo code example for retrying a database operation:
void DoSomethingAndRetry(value)
{
try
{
SaveToDatabase(value);
}
catch(DeadlockException ex)
{
//deadlock happened, we are retrying the SQL statement
SaveToDatabase(value);
}
}
Letting the exception bubble up
Let's assume your method is public. If an exception happens which implies that the method failed and you can't continue execution, then the exception should bubble up, so that the calling code can handle it accordingly. It depends one the use-case how the calling code would react on the exception.
Before letting the exception bubble up you may wrap it into another application specific exception as inner exception to add additional context information. You may also process the exception somehow, E.g log it , or leave the logging to the calling code, depending on your logging architecture.
public bool SaveSomething(value)
{
try
{
SaveToFile(value);
}
catch(FileNotFoundException ex)
{
//process exception if needed, E.g. log it
ProcessException(ex);
//you may want to wrap this exception into another one to add context info
throw WrapIntoNewExceptionWithSomeDetails(ex);
}
}
Documenting possible exceptions
In .NET it is also helpful to define which exceptions your method is throwing and reasons why it might throw it. So that the calling code can take this into consideration. See https://msdn.microsoft.com/en-us/library/w1htk11d.aspx
Example:
/// <exception cref="System.Exception">Thrown when something happens..</exception>
DoSomethingWith(value)
{
...
}
Ignoring exceptions
For methods where you are OK with a failing method and don't want to add a try catch block around it all the time, you could create a method with similar signature:
public bool TryDoSomethingWith(value)
{
try
{
DoSomethingWith(value);
return true;
}
catch(Exception ex)
{
//process exception if needed, e.g. log it
ProcessException(ex);
return false;
}
}

adding custom font in my app

while adding custom font in my app, it's crashing some time.
But most of the time it get executed smoothly.
i'm using following code.
try {
// Get the typeface
ShravyaApp.appTypeFace = Typeface.createFromAsset(getApplication().getAssets(),
"kadage.ttf");
Log.d("font","in type="+ShravyaApp.fontName);
Log.d("font","type face="+ShravyaApp.appTypeFace);
}
catch (Exception e)
{
ShravyaApp.appTypeFace = Typeface.createFromAsset(getApplication().getAssets(),
"kadage.ttf");
Log.d("font","in catch typr="+ShravyaApp.fontName);
Log.d("font","type face="+ShravyaApp.appTypeFace);
//Log.e(TAG, "Could not get typeface '" + + "' because " + e.getMessage());
e.printStackTrace();
}
The Error i'm getting is :
NullPointerException
at android.graphics.Typeface.nativeCreateFromAsset(Native Method)
at android.graphics.Typeface.createFromAsset(Typeface.java:280)
This could be IO Exceptions in the nativeCreateFromAsset. Also this can be because you are calling this method before Activity onCreate().
Any way try using retry mechanism with 100 milliseconds sleeping between retries, there is no reason that it will not work, unless some bug in the user device.
Why place the same code in both try and catch?
I suggest you use a Typface-cache (example here) and if your app really requires the font, you may want to refactor your method into a recursive one and as Babibu said, pause in between.
I am guessing getApplication() is the function that returns a null pointer. It needs to be called in the onCreate(), not in the constructor. We need more context to be sure.
Also you can set a breakpoint catching null pointer exceptions in the debug mode.

Resources