Best Mockito code snippet using org.mockito.internal.exceptions.Reporter.delegatedMethodDoesNotExistOnDelegate
Source: ForwardsInvocations.java
2 * Copyright (c) 2007 Mockito contributors3 * This program is made available under the terms of the MIT License.4 */5package org.mockito.internal.stubbing.defaultanswers;6import static org.mockito.internal.exceptions.Reporter.delegatedMethodDoesNotExistOnDelegate;7import static org.mockito.internal.exceptions.Reporter.delegatedMethodHasWrongReturnType;8import java.io.Serializable;9import java.lang.reflect.InvocationTargetException;10import java.lang.reflect.Method;11import org.mockito.internal.configuration.plugins.Plugins;12import org.mockito.invocation.Invocation;13import org.mockito.invocation.InvocationOnMock;14import org.mockito.plugins.MemberAccessor;15import org.mockito.stubbing.Answer;16/**17 * Internal answer to forward invocations on a real instance.18 *19 * @since 1.9.520 */21public class ForwardsInvocations implements Answer<Object>, Serializable {22 private static final long serialVersionUID = -8343690268123254910L;23 private Object delegatedObject = null;24 public ForwardsInvocations(Object delegatedObject) {25 this.delegatedObject = delegatedObject;26 }27 public Object answer(InvocationOnMock invocation) throws Throwable {28 Method mockMethod = invocation.getMethod();29 try {30 Method delegateMethod = getDelegateMethod(mockMethod);31 if (!compatibleReturnTypes(32 mockMethod.getReturnType(), delegateMethod.getReturnType())) {33 throw delegatedMethodHasWrongReturnType(34 mockMethod, delegateMethod, invocation.getMock(), delegatedObject);35 }36 MemberAccessor accessor = Plugins.getMemberAccessor();37 Object[] rawArguments = ((Invocation) invocation).getRawArguments();38 return accessor.invoke(delegateMethod, delegatedObject, rawArguments);39 } catch (NoSuchMethodException e) {40 throw delegatedMethodDoesNotExistOnDelegate(41 mockMethod, invocation.getMock(), delegatedObject);42 } catch (InvocationTargetException e) {43 // propagate the original exception from the delegate44 throw e.getCause();45 }46 }47 private Method getDelegateMethod(Method mockMethod) throws NoSuchMethodException {48 if (mockMethod.getDeclaringClass().isAssignableFrom(delegatedObject.getClass())) {49 // Compatible class. Return original method.50 return mockMethod;51 } else {52 // Return method of delegate object with the same signature as mockMethod.53 return delegatedObject54 .getClass()...
How should I handle a UnnecessaryStubbingException that is sensitive to ordering in underlying data structures?
Mockito verify no more interactions with any mock
Java Enumerating list in mockito's thenReturn
Mock object method call using Spring Boot and Mockito
Can I use Mockito to insert a delay and then call the real method?
Can Mockito stub a method without regard to the argument?
What is the difference between mock() and stub() when using Mockito?
Mockito when method not working
mock a CrudRepository findById ("111").get ()
How to use @InjectMocks along with @Autowired annotation in Junit
Lenient mocks are what you want, if you can't just use a real UserKeychain.
Mockito.lenient().when(userKeychain.getUserStatus()).thenReturn(UserState.OK);
Mockito.lenient().when(otherUserKeychain.getUserStatus()).thenReturn(UserState.SUSPENDED);
Mockito is designed to replace systems where you can't use the real system in your test, particularly in systems that predictably invoke services instead of getting properties from data objects (or other idempotent actions). Because your system doesn't call those methods in a deterministic order, and because the calls aren't expensive and don't have side effects, I would recommend just going with the "lenient" option.
Imagine this case instead, where you are testing deleting user 1001
:
when(userRpc.deleteUser(1001)).thenReturn(RPC_SUCCESS);
when(userRpc.deleteUser(1002)).thenReturn(RPC_SUCCESS); // unnecessary
The test might pass if you ever delete the wrong user: Over-stubbing has masked a problem. Compare with this:
when(userRpc.fetchExpensiveUserDetails(1001)).thenReturn(user1001);
when(userRpc.fetchExpensiveUserDetails(1002)).thenReturn(user1002); // unnecessary
Depending on what you're testing, this might be dangerous, but might not be so bad. Simulating a slow mobile network or with expensive data, maybe it is entirely against spec for you to fetch too much. However, in other cases, it may be acceptable. Finally, compare this case:
when(calculationResult.getRealComponent()).thenReturn(-1d);
when(calculationResult.getComplexComponent()).thenReturn(5);
when(calculationResult.getShortString()).thenReturn("-1 + 5i");
calculationResult
looks an awful lot like a data object, and it is probably not a critical part of your test which of your methods to call or whether you're calling all of them. This is a case where Mockito's strict stubbing hinders you rather than helping you, and might be a case where you want to make some of those stubbings lenient. You might also choose to make the entire mock lenient, which particularly makes sense if you were to create a test helper method like stubCalculationResult(-1, 5)
that prepared an entire object for you like that.
The only option better than that is to use a real object. In my example, if CalculationResult is an existing well-defined object, it may be lower risk overall to use a real one than to mock the behavior you believe at test-writing time to be correct. Similarly for your case, if you have access to a UserKeychain constructor that populates UserStatus etc, then it may be safer to use that in a test.
Though this might appear at first glance to be a slippery slope into turning a unit test into an integration test, I'd like to clarify that I'm recommending this only for data objects, which have no dependencies, and which ideally are immutable objects that have no methods with side-effects. If you use dependency injection, these are the type of single-implementation data holders that you would call new
on rather than getting from your graph. This is also a good reason to separate your data objects so they are immutable and easy to construct, and to shift your services to consume those objects rather than giving methods to the data objects (favoring loginService.login(user)
rather than user.login(loginService)
).
Check out the latest blogs from LambdaTest on this topic:
Hey everyone! We hope you had a great Hacktober. At LambdaTest, we thrive to bring you the best with each update. Our engineering and tech teams work at lightning speed to deliver you a seamless testing experience.
Before we discuss the Joomla testing, let us understand the fundamentals of Joomla and how this content management system allows you to create and maintain web-based applications or websites without having to write and implement complex coding requirements.
The sky’s the limit (and even beyond that) when you want to run test automation. Technology has developed so much that you can reduce time and stay more productive than you used to 10 years ago. You needn’t put up with the limitations brought to you by Selenium if that’s your go-to automation testing tool. Instead, you can pick from various test automation frameworks and tools to write effective test cases and run them successfully.
I think that probably most development teams describe themselves as being “agile” and probably most development teams have standups, and meetings called retrospectives.There is also a lot of discussion about “agile”, much written about “agile”, and there are many presentations about “agile”. A question that is often asked is what comes after “agile”? Many testers work in “agile” teams so this question matters to us.
In an ideal world, you can test your web application in the same test environment and return the same results every time. The reality can be difficult sometimes when you have flaky tests, which may be due to the complexity of the web elements you are trying to perform an action on your test case.
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!