JUnit mocking with Mockito, EasyMock, etc - java

I'm trying to mock a method of an object inside the class I'm testing.
For instance
class ClassToTest {
public doSomething () {
SomeObject a = new SomeObject ();
a.doSomethingElse ();
}
}
Is there a way to mock the methods of the variable "a"? I'd like doSomethingElse to do nothing during testing. I'm currently using Mockito but I'm open to any mocking framework.
Thanks

Yes, there is a way, as shown by the following JMockit test:
public void testDoSomething(final SomeObject mock)
{
new ClassToTest().doSomething();
new Verifications() {{ mock.doSomethingElse(); }};
}
No need to refactor code under test to use a wrapper, DI, etc; simply mock whatever you need to be mocked.

It's not possible to mock the reference "a" when it's declared as a local variable, as in your case. You could consider injecting the dependency to SomeObject, e.g. as a parameter of doSomething method. That way, you can inject a mock of SomeObject in your test instead.
One of the benefits of dependency injection is increased testability.

With some refactoring it is possible, of course:
class SomeObject {
public void doSomethingElse()
{
}
}
class ClassToTest
{
private final SomeObject someObject;
public void doSomething()
{
someObject.doSomethingElse();
}
public ClassToTest(SomeObject someObject)
{
this.someObject = someObject;
}
}
class Test {
#Test
public void testDoSomething()
{
SomeObject someObject = Mockito.mock(SomeObject.class);
new ClassToTest(someObject).doSomething();
Mockito.verify(someObject, Mockito.atLeastOnce()).doSomethingElse();
}
}

I believe you can use EasyMock Class Extensions for EasyMock 2.5 or earlier, and apparently it is included in 3.0. See this part of the previous page for information on what you are trying to do. That said, I haven't personally tried to do that, so I don't know how well it will work.

If you want a new instance in each call, I'd suggest refactoring in the following way:
class ClassToTest {
public doSomething () {
SomeObject a = getInstance();
a.doSomethingElse ();
}
protected SomeObject getInstance() {
return new SomeObject();
}
}
Then you can create a testclass extending ClassToTest, overriding the getInstance() method, with one supplying a mock object.
This is of course only viable if you are ok with exposing the getInstance() method, so I don't recommend it if the class is part of a public API. If this is the case, consider supplying a factory class using dependency injection.

class ClassToTest {
private SomethingElseInterface somethingElseDoer ;
public ClassToTest(SomethingElseInterface somethingElseDoer) {
this.somethingElseDoer = somethingElseDoer;
}
public doSomething () {
somethingElseDoer.doSomethingElse();
}
}
And where you use it:
SomethingElseInterface somethingElseDoer = ...; // in a test, this is where you mock it
ClassToTest foo = new ClassToTest(somethingElseDoer); // inject through constructor
foo.doSomething();

Related

How to mock a global object in a class properly?

Let say I have a class like so
Class A{
private K Obj = (K)(AppContext.getSpringContext().getBean("obj"))
public void method1{
// uses Obj
}
public void method2{
// uses Obj
}
}
And I need to write junits for method1 and method2 by changing the behavior of Obj in method 1 and method 2. In my junit class I am setting the appcontext as so:
public class AccountInformationManagerTest {
private CCBSAppContext appContext;
#Mock
ApplicationContext springContext;
#Mock
Object obj;
#Before
public void setup() throws Exception {
appContext = new CCBSAppContext();
appContext.setApplicationContext(springContext);
Mockito.when(springContext.getBean("obj")).thenReturn(obj);
}
}
As you can see, I am setting globally the appcontext. I don't want mock the static calls as I am using jacoco and powermockito doesn't integrate very well with jacoco. The problem here is that appcontext is now a global object which is shared across all methods and I need to modify the behavior of obj as I test the two methods. This will create a concurrency issue. How can I resolve this?
TBH avoid (K)(AppContext.getSpringContext().getBean("obj")) directly inject dependency or autowire the dependency . Then in its easily testable and add obj to the class via SpringTestUtils or setters.
#Autowired
K obj;
Else you can mock springContext getBean method for every test
#Test
void fun {
Mockito.when(springContext.getBean(Mockito.eq("obj"))).thenReturn(obj);
// doSomething
}
#Test
void fun2 {
Mockito.when(springContext.getBean(Mockito.eq("obj"))).thenReturn(obj2);
// doSomething2
}
Use reflection to set the Obj. Then you can set Obj to be a mocked object.
Here is a SO answer describing how to do it.

Java Mockito Test Static property assign with function [duplicate]

I've written a factory to produce java.sql.Connection objects:
public class MySQLDatabaseConnectionFactory implements DatabaseConnectionFactory {
#Override public Connection getConnection() {
try {
return DriverManager.getConnection(...);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
I'd like to validate the parameters passed to DriverManager.getConnection, but I don't know how to mock a static method. I'm using JUnit 4 and Mockito for my test cases. Is there a good way to mock/verify this specific use-case?
Use PowerMockito on top of Mockito.
Example code:
#RunWith(PowerMockRunner.class)
#PrepareForTest(DriverManager.class)
public class Mocker {
#Test
public void shouldVerifyParameters() throws Exception {
//given
PowerMockito.mockStatic(DriverManager.class);
BDDMockito.given(DriverManager.getConnection(...)).willReturn(...);
//when
sut.execute(); // System Under Test (sut)
//then
PowerMockito.verifyStatic();
DriverManager.getConnection(...);
}
More information:
Why doesn't Mockito mock static methods?
Mocking of static methods in Mockito is possible since Mockito 3.4.0.
For more details see:
https://github.com/mockito/mockito/releases/tag/v3.4.0
https://github.com/mockito/mockito/issues/1013
https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#static_mocks
assertEquals("foo", Foo.method());
try (MockedStatic mocked = mockStatic(Foo.class)) {
mocked.when(Foo::method).thenReturn("bar");
assertEquals("bar", Foo.method());
mocked.verify(Foo::method);
}
assertEquals("foo", Foo.method());
In your case, something like this:
#Test
public void testStaticMockWithVerification() throws SQLException {
try (MockedStatic<DriverManager> dummy = Mockito.mockStatic(DriverManager.class)) {
DatabaseConnectionFactory factory = new MySQLDatabaseConnectionFactory();
dummy.when(() -> DriverManager.getConnection("arg1", "arg2", "arg3"))
.thenReturn(new Connection() {/*...*/});
factory.getConnection();
dummy.verify(() -> DriverManager.getConnection(eq("arg1"), eq("arg2"), eq("arg3")));
}
}
NOTE: mocking STATIC METHODS requires mockito-inline dependency instead of mockito-core.
For JUnit5 also add this:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
The typical strategy for dodging static methods that you have no way of avoiding using, is by creating wrapped objects and using the wrapper objects instead.
The wrapper objects become facades to the real static classes, and you do not test those.
A wrapper object could be something like
public class Slf4jMdcWrapper {
public static final Slf4jMdcWrapper SINGLETON = new Slf4jMdcWrapper();
public String myApisToTheSaticMethodsInSlf4jMdcStaticUtilityClass() {
return MDC.getWhateverIWant();
}
}
Finally, your class under test can use this singleton object by, for example,
having a default constructor for real life use:
public class SomeClassUnderTest {
final Slf4jMdcWrapper myMockableObject;
/** constructor used by CDI or whatever real life use case */
public myClassUnderTestContructor() {
this.myMockableObject = Slf4jMdcWrapper.SINGLETON;
}
/** constructor used in tests*/
myClassUnderTestContructor(Slf4jMdcWrapper myMock) {
this.myMockableObject = myMock;
}
}
And here you have a class that can easily be tested, because you do not directly use a class with static methods.
If you are using CDI and can make use of the #Inject annotation then it is even easier.
Just make your Wrapper bean #ApplicationScoped, get that thing injected as a collaborator (you do not even need messy constructors for testing), and go on with the mocking.
I had a similar issue. The accepted answer did not work for me, until I made the change: #PrepareForTest(TheClassThatContainsStaticMethod.class), according to PowerMock's documentation for mockStatic.
And I don't have to use BDDMockito.
My class:
public class SmokeRouteBuilder {
public static String smokeMessageId() {
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
log.error("Exception occurred while fetching localhost address", e);
return UUID.randomUUID().toString();
}
}
}
My test class:
#RunWith(PowerMockRunner.class)
#PrepareForTest(SmokeRouteBuilder.class)
public class SmokeRouteBuilderTest {
#Test
public void testSmokeMessageId_exception() throws UnknownHostException {
UUID id = UUID.randomUUID();
mockStatic(InetAddress.class);
mockStatic(UUID.class);
when(InetAddress.getLocalHost()).thenThrow(UnknownHostException.class);
when(UUID.randomUUID()).thenReturn(id);
assertEquals(id.toString(), SmokeRouteBuilder.smokeMessageId());
}
}
As mentioned before you can not mock static methods with mockito.
If changing your testing framework is not an option you can do the following:
Create an interface for DriverManager, mock this interface, inject it via some kind of dependency injection and verify on that mock.
For those who use JUnit 5, Powermock is not an option. You'll require the following dependencies to successfully mock a static method with just Mockito.
testCompile group: 'org.mockito', name: 'mockito-core', version: '3.6.0'
testCompile group: 'org.mockito', name: 'mockito-junit-jupiter', version: '3.6.0'
testCompile group: 'org.mockito', name: 'mockito-inline', version: '3.6.0'
mockito-junit-jupiter add supports for JUnit 5.
And support for mocking static methods is provided by mockito-inline dependency.
Example:
#Test
void returnUtilTest() {
assertEquals("foo", UtilClass.staticMethod("foo"));
try (MockedStatic<UtilClass> classMock = mockStatic(UtilClass.class)) {
classMock.when(() -> UtilClass.staticMethod("foo")).thenReturn("bar");
assertEquals("bar", UtilClass.staticMethod("foo"));
}
assertEquals("foo", UtilClass.staticMethod("foo"));
}
The try-with-resource block is used to make the static mock remains temporary, so it's mocked only within that scope.
When not using a try block, make sure to close the mock, once you are done with the assertions.
MockedStatic<UtilClass> classMock = mockStatic(UtilClass.class)
classMock.when(() -> UtilClass.staticMethod("foo")).thenReturn("bar");
assertEquals("bar", UtilClass.staticMethod("foo"));
classMock.close();
Mocking void methods:
When mockStatic is called on a class, all the static void methods in that class automatically get mocked to doNothing().
Observation : When you call static method within a static entity, you need to change the class in #PrepareForTest.
For e.g. :
securityAlgo = MessageDigest.getInstance(SECURITY_ALGORITHM);
For the above code if you need to mock MessageDigest class, use
#PrepareForTest(MessageDigest.class)
While if you have something like below :
public class CustomObjectRule {
object = DatatypeConverter.printHexBinary(MessageDigest.getInstance(SECURITY_ALGORITHM)
.digest(message.getBytes(ENCODING)));
}
then, you'd need to prepare the class this code resides in.
#PrepareForTest(CustomObjectRule.class)
And then mock the method :
PowerMockito.mockStatic(MessageDigest.class);
PowerMockito.when(MessageDigest.getInstance(Mockito.anyString()))
.thenThrow(new RuntimeException());
You can do it with a little bit of refactoring:
public class MySQLDatabaseConnectionFactory implements DatabaseConnectionFactory {
#Override public Connection getConnection() {
try {
return _getConnection(...some params...);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
//method to forward parameters, enabling mocking, extension, etc
Connection _getConnection(...some params...) throws SQLException {
return DriverManager.getConnection(...some params...);
}
}
Then you can extend your class MySQLDatabaseConnectionFactory to return a mocked connection, do assertions on the parameters, etc.
The extended class can reside within the test case, if it's located in the same package (which I encourage you to do)
public class MockedConnectionFactory extends MySQLDatabaseConnectionFactory {
Connection _getConnection(...some params...) throws SQLException {
if (some param != something) throw new InvalidParameterException();
//consider mocking some methods with when(yourMock.something()).thenReturn(value)
return Mockito.mock(Connection.class);
}
}
I also wrote a combination of Mockito and AspectJ: https://github.com/iirekm/varia/tree/develop/ajmock
Your example becomes:
when(() -> DriverManager.getConnection(...)).thenReturn(...);
Mockito cannot capture static methods, but since Mockito 2.14.0 you can simulate it by creating invocation instances of static methods.
Example (extracted from their tests):
public class StaticMockingExperimentTest extends TestBase {
Foo mock = Mockito.mock(Foo.class);
MockHandler handler = Mockito.mockingDetails(mock).getMockHandler();
Method staticMethod;
InvocationFactory.RealMethodBehavior realMethod = new InvocationFactory.RealMethodBehavior() {
#Override
public Object call() throws Throwable {
return null;
}
};
#Before
public void before() throws Throwable {
staticMethod = Foo.class.getDeclaredMethod("staticMethod", String.class);
}
#Test
public void verify_static_method() throws Throwable {
//register staticMethod call on mock
Invocation invocation = Mockito.framework().getInvocationFactory().createInvocation(mock, withSettings().build(Foo.class), staticMethod, realMethod,
"some arg");
handler.handle(invocation);
//verify staticMethod on mock
//Mockito cannot capture static methods so we will simulate this scenario in 3 steps:
//1. Call standard 'verify' method. Internally, it will add verificationMode to the thread local state.
// Effectively, we indicate to Mockito that right now we are about to verify a method call on this mock.
verify(mock);
//2. Create the invocation instance using the new public API
// Mockito cannot capture static methods but we can create an invocation instance of that static invocation
Invocation verification = Mockito.framework().getInvocationFactory().createInvocation(mock, withSettings().build(Foo.class), staticMethod, realMethod,
"some arg");
//3. Make Mockito handle the static method invocation
// Mockito will find verification mode in thread local state and will try verify the invocation
handler.handle(verification);
//verify zero times, method with different argument
verify(mock, times(0));
Invocation differentArg = Mockito.framework().getInvocationFactory().createInvocation(mock, withSettings().build(Foo.class), staticMethod, realMethod,
"different arg");
handler.handle(differentArg);
}
#Test
public void stubbing_static_method() throws Throwable {
//register staticMethod call on mock
Invocation invocation = Mockito.framework().getInvocationFactory().createInvocation(mock, withSettings().build(Foo.class), staticMethod, realMethod,
"foo");
handler.handle(invocation);
//register stubbing
when(null).thenReturn("hey");
//validate stubbed return value
assertEquals("hey", handler.handle(invocation));
assertEquals("hey", handler.handle(invocation));
//default null value is returned if invoked with different argument
Invocation differentArg = Mockito.framework().getInvocationFactory().createInvocation(mock, withSettings().build(Foo.class), staticMethod, realMethod,
"different arg");
assertEquals(null, handler.handle(differentArg));
}
static class Foo {
private final String arg;
public Foo(String arg) {
this.arg = arg;
}
public static String staticMethod(String arg) {
return "";
}
#Override
public String toString() {
return "foo:" + arg;
}
}
}
Their goal is not to directly support static mocking, but to improve its public APIs so that other libraries, like Powermockito, don't have to rely on internal APIs or directly have to duplicate some Mockito code. (source)
Disclaimer: Mockito team thinks that the road to hell is paved with static methods. However, Mockito's job is not to protect your code from static methods. If you don’t like your team doing static mocking, stop using Powermockito in your organization. Mockito needs to evolve as a toolkit with an opinionated vision on how Java tests should be written (e.g. don't mock statics!!!). However, Mockito is not dogmatic. We don't want to block unrecommended use cases like static mocking. It's just not our job.
To mock static method you should use a Powermock look at:
https://github.com/powermock/powermock/wiki/MockStatic.
Mockito doesn't provide this functionality.
You can read nice a article about mockito:
http://refcardz.dzone.com/refcardz/mockito
I found one solution in Mockito. This feature comes with a version only from 3.4.0
https://asolntsev.github.io/en/2020/07/11/mockito-static-methods/
dependency
In your build.gradle replace mockito-core:3.3.3 by mockito-inline:3.4.0:
testImplementation('org.mockito:mockito-inline:3.4.0')
what are we going to mock
class Buddy
{
static String name()
{
return "John";
}
}
Mock the static method
#Test
void lookMomICanMockStaticMethods()
{
assertThat(Buddy.name()).isEqualTo("John");
try (MockedStatic<Buddy> theMock = Mockito.mockStatic(Buddy.class))
{
theMock.when(Buddy::name).thenReturn("Rafael");
assertThat(Buddy.name()).isEqualTo("Rafael");
}
assertThat(Buddy.name()).isEqualTo("John");
}
I think this could help us.
Since that method is static, it already has everything you need to use it, so it defeats the purpose of mocking.
Mocking the static methods is considered to be a bad practice.
If you try to do that, it means there is something wrong with the way you want to perform testing.
Of course you can use PowerMockito or any other framework capable of doing that, but try to rethink your approach.
For example: try to mock/provide the objects, which that static method consumes instead.
When you try to mock the static method, you have to write the test inside the try block. because It's important to note that scoped mocks must be closed by the entity that activates the mock.
try (MockedStatic<Tester> tester = Mockito.mockStatic(Tester.class)) {
tester.when(() -> Tester.testStatic("Testing..")).thenReturn(mock(ReturnObject.class));
//Here you have to write the test cases
}
In the above example, we have to mock the Tester Class testStatic Method with input param as "Testing...". Here, this method will return a ReturnObject class type object. Hence we write mockito when chain like above.
Don't forget to add below dependency in your Gradle/maven
testImplementation 'org.mockito:mockito-inline:4.3.1'
Use JMockit framework. It worked for me. You don't have to write statements for mocking DBConenction.getConnection() method. Just the below code is enough.
#Mock below is mockit.Mock package
Connection jdbcConnection = Mockito.mock(Connection.class);
MockUp<DBConnection> mockUp = new MockUp<DBConnection>() {
DBConnection singleton = new DBConnection();
#Mock
public DBConnection getInstance() {
return singleton;
}
#Mock
public Connection getConnection() {
return jdbcConnection;
}
};
There is an easy solution by using java FunctionalInterface and then add that interface as dependency for the class you are trying to unit test.
For mocking static functions i was able to do it that way:
create a wrapper function in some helper class/object. (using a name variant might be beneficial for keeping things separated and maintainable.)
use this wrapper in your codes. (Yes, codes need to be realized with testing in mind.)
mock the wrapper function.
wrapper code snippet (not really functional, just for illustration)
class myWrapperClass ...
def myWrapperFunction (...) {
return theOriginalFunction (...)
}
of course having multiple such functions accumulated in a single wrapper class might be beneficial in terms of code reuse.
Here I share my mockito MockStatic solution based on an extension as promised in my answer to leokom's solution.
So, why does Mockito choose try-with-resources? Well, simply because they want to keep a tidy ship. That is good programming after all. Try-with-resources allows construction with guaranteed calling of the close method. But in JUnit we already have that in BeforeEach and AfterEach. And one can easily add these for a generic purpose to each test class using an Extension that implements BeforeEachCallback and AfterEachCallback.
So much for the theory. Let's make a static mock for
Instant.now()
I started with an annotation to be able to mark the fields in my test class that I want to use as static mocks.
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.FIELD)
public #interface StaticMock {
}
This allows me to create a field in my test class for static mocking that I can easily find in my Extension class.
#StaticMock
private MockedStatic<Instant> staticInstantMock;
I added the Extension I created to my test class. You have two options.
Create an Extension for this purpose and add it to the class next to MockitoExtension, which you also need.
Create an Extension and have it inherit from MockitoExtension. Now you can replace MockitoExtension on your test class.
I used the latter of the two.
#ExtendWith({CompanyMockitoExtension.class})
class MyExtendedTestClass {
Now we need something to be returned for the static when it's called:
#Mock
private Instant now;
staticInstantMock.when(Instant::now).thenReturn(now);
The whole test class:
#ExtendWith({CompanyMockitoExtension.class})
class MyExtendedTestClass {
#StaticMock
private MockedStatic<Instant> staticInstantMock;
#Mock
private Instant now;
#Test
void myTestMethod() {
staticInstantMock.when(Instant::now).thenReturn(now);
assertThat(Instant::now).isSameAs(now); // This would normally happen in the class you are testing...
}
}
Now let's take a look at the Extension class.
import static org.mockito.Mockito.mockStatic;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
public class CompanyMockitoExtension extends MockitoExtension {
#Override
public void beforeEach(ExtensionContext context) {
super.beforeEach(context); // Don't forget to call the super!!
if (context.getTestInstance().isEmpty()) { // Just to be sure...
return;
}
// Get the unit test instance
Object testSubject = context.getTestInstance().get();
initializeStaticMocks(testSubject);
}
private void initializeStaticMocks(Object testSubject) {
// Find all fields that I want to static mock
List<Field> staticMockFields = ReflectionHelper.getFieldsWithAnnotation(testSubject, StaticMock.class);
staticMockFields.forEach(field -> initializeStaticMock(field, testSubject));
}
private void initializeStaticMock(Field field, Object testSubject) {
// Get the type of the static mock. It is within the generic MockedStatic<> class type.
Class<?> typeForStaticMock = (Class<?>) ReflectionHelper.getTypesForGeneric(field)[0];
try {
// Now set the field with the mockStatic method of Mockito.
field.setAccessible(true);
field.set(testSubject, mockStatic(typeForStaticMock));
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to instantiate Static Mock with type: " + typeForStaticMock.getName());
}
}
#Override
public void afterEach(ExtensionContext context) {
super.afterEach(context); // Again, do not forget to call the super.
if (context.getTestInstance().isEmpty()) {
return;
}
Object testSubject = context.getTestInstance().get();
closeStaticMocks(testSubject); // Close all static mocks.
}
private void closeStaticMocks(Object testSubject) {
// Again find all fields we annotated
List<Field> staticMockFields = ReflectionHelper.getFieldsWithAnnotation(testSubject, StaticMock.class);
staticMockFields.forEach(field -> closeStaticMock(field, testSubject));
}
private void closeStaticMock(Field field, Object testSubject) {
// Get the instance and simply call close.
MockedStatic<?> mockedStaticInstance = ReflectionHelper.getFieldInstance(field, testSubject, MockedStatic.class);
mockedStaticInstance.close();
}
}
The nice thing about this extension is that you can add additional mocking stuff. I added verification of no more interactions on all mocks in the AfterEach. This is now automatic when we use this extension. I also added similar behavior for construction mocking as for the static mocking.
As you see, I made my own reflection helper class. I know there are some standard reflection helper classes and those might be better. Here is mine for this purpose.
public class ReflectionHelper {
public static List<Field> getFieldsWithAnnotation(
Object testSubject,
Class<? extends Annotation> annotationType
) {
Class<?> testSubjectClass = testSubject.getClass();
return Arrays.stream(testSubjectClass.getDeclaredFields())
.filter(field -> field.isAnnotationPresent(annotationType))
.collect(toUnmodifiableList());
}
public static List<Field> getCollectionFields(Object testSubject) {
Class<?> testSubjectClass = testSubject.getClass();
return Arrays.stream(testSubjectClass.getDeclaredFields())
.filter(field -> Collection.class.isAssignableFrom(field.getType()))
.collect(toUnmodifiableList());
}
#SuppressWarnings("unchecked")
public static <T> T getFieldInstance(Field field, Object testSubject, Class<T> type) {
return (T) getFieldInstance(field, testSubject);
}
public static Object getFieldInstance(Field field, Object testSubject) {
try {
boolean isStatic = isStatic(field.getModifiers());
Object context = isStatic ? null : testSubject;
field.setAccessible(true);
return field.get(context);
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to get instance of field.");
}
}
public static Type[] getTypesForGeneric(Field field) {
ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
return parameterizedType.getActualTypeArguments();
}
}
Refactor it a little bit:
public class MySQLDatabaseConnectionFactory implements DatabaseConnectionFactory {
ConnectionSupplier connectionSupplier = () -> SupplierDriverManager.getConnection();
public void setConnSupplier(ConnectionSupplier supplier) {
this.connectionSupplier = supplier;
}
#Override
public Connection getConnection() {
try {
return connectionSupplier.conn();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
#FunctionalInterface
interface ConnectionSupplier {
Connection conn();
}
}
Then you can use the mockito:
MySQLDatabaseConnectionFactory.ConnectionSupplier connectionSupplier = mock(MySQLDatabaseConnectionFactory.ConnectionSupplier.class);
when(connectionSupplier.conn()).thenReturn(yourMockObject);
yourConnectionFactory.setConnSupplier(connectionSupplier);

How to mock local variable obtained from another method of tested class?

I have following class
class MyClass{
public void m(InputStream is){
...
Parser eParser = getExcelFileParser();
eParser.parse(is);
...
eParser.foo();
eParser.bar();
}
public ExcelFileParser getExcelFileParser(){
...
}
}
How to write unit test for method m at this situation? I want to mock eParser object only.
Is it possible?
I use Mockito and PowerMockito
You can do what you want in Mockito (no PowerMock needed) using a spy without changing your code at all.
In your unit test you need to do something like the following:
ExcelFileParser parser = mock(ExcelFileParser.class);
MyClass myClass = spy(new MyClass());
doReturn(parser).when(myClass).getExcelFileParser();
Can you pass AnotherObject as a parameter into the method m rather than calling getAnotherObject() in the method itself?
Preface: I use EasyMock not Mockito so this may be a bit off.
Can't you create an inner subclass of MyClass in your test that overrides getExcelFileParser and has it return a mock? Like this:
public class MyClassMock extends MyClass {
ExcelFileParser _mock;
public MyClassMock(ExcelFileParser mock) {
_mock = mock;
}
#Override
public ExcelFileParser getExcelFileParser() {
return _mock;
}
}
I haven't tested this so there could be issues with this, but the basic idea should be right.

Exception : mockito wanted but not invoked, Actually there were zero interactions with this mock

I have interface
Interface MyInterface {
myMethodToBeVerified (String, String);
}
And implementation of interface is
class MyClassToBeTested implements MyInterface {
myMethodToBeVerified(String, String) {
…….
}
}
I have another class
class MyClass {
MyInterface myObj = new MyClassToBeTested();
public void abc(){
myObj.myMethodToBeVerified (new String(“a”), new String(“b”));
}
}
I am trying to write JUnit for MyClass. I have done
class MyClassTest {
MyClass myClass = new MyClass();
#Mock
MyInterface myInterface;
testAbc(){
myClass.abc();
verify(myInterface).myMethodToBeVerified(new String(“a”), new String(“b”));
}
}
But I am getting mockito wanted but not invoked, Actually there were zero interactions with this mock at verify call.
can anyone suggest some solutions.
You need to inject mock inside the class you're testing. At the moment you're interacting with the real object, not with the mock one. You can fix the code in a following way:
void testAbc(){
myClass.myObj = myInteface;
myClass.abc();
verify(myInterface).myMethodToBeVerified(new String("a"), new String("b"));
}
although it would be a wiser choice to extract all initialization code into #Before
#Before
void setUp(){
myClass = new myClass();
myClass.myObj = myInteface;
}
#Test
void testAbc(){
myClass.abc();
verify(myInterface).myMethodToBeVerified(new String("a"), new String("b"));
}
Your class MyClass creates a new MyClassToBeTested, instead of using your mock. My article on the Mockito wiki describes two ways of dealing with this.
#Jk1's answer is fine, but Mockito also allows for more succinct injection using annotations:
#InjectMocks MyClass myClass; //#InjectMocks automatically instantiates too
#Mock MyInterface myInterface
But regardless of which method you use, the annotations are not being processed (not even your #Mock) unless you somehow call the static MockitoAnnotation.initMocks() or annotate the class with #RunWith(MockitoJUnitRunner.class).
#jk1 answer is perfect, since #igor Ganapolsky asked, why can't we use Mockito.mock here? i post this answer.
For that we have provide one setter method for myobj and set the myobj value with mocked object.
class MyClass {
MyInterface myObj;
public void abc() {
myObj.myMethodToBeVerified (new String("a"), new String("b"));
}
public void setMyObj(MyInterface obj)
{
this.myObj=obj;
}
}
In our Test class, we have to write below code
class MyClassTest {
MyClass myClass = new MyClass();
#Mock
MyInterface myInterface;
#test
testAbc() {
myclass.setMyObj(myInterface); //it is good to have in #before method
myClass.abc();
verify(myInterface).myMethodToBeVerified(new String("a"), new String("b"));
}
}
This exception can also be thrown if say, you expect thisMethod() to execute, but it didn't. It didn't because it's inside a condition that was not met.
For example, if you have some unit test that says verify thisMethod() is executed, but in fact, it was not because varX and varY are not equal.
//method expected to be called.
if( varX == varY){
thisMethod();
}
//test
Mockito.verify(foo).thisMethod();

how to partial mock public method using PowerMock?

Following is my class
public class SomeClass {
public ReturnType1 testThisMethod(Type1 param1, Type2 param2) {
//some code
helperMethodPublic(param1,param2);
//more code follows
}
public ReturnType2 helperMethodPublic(Type1 param1, Type2 param2) {
//some code
}
}
So in the above class while testing testThisMethod(), I want to partially mock helperMethodPublic().
As of now, I am doing the following:
SomeClass someClassMock =
PowerMock.createPartialMock(SomeClass.class,"helperMethodPublic");
PowerMock.expectPrivate(someClassMock, "helperMethodPublic, param1, param2).
andReturn(returnObject);
The compiler doesn't complain. So I try to run my test and when the code hits the helperMethodPublic() method, the control goes into the method and starts to execute each line of code in there. How do I prevent this from happening?
Another solution that doesn't rely on a mock framework would be to override 'helperMethodPublic' in an anonymous subclass defined within your test:
SomeClass sc = new SomeClass() {
#Override
public ReturnType2 helperMethodPublic(Type1 p1, Type2 p2) {
return returnObject;
}
};
Then when you use this instance in your test it will run the original version of 'testThisMethod' and the overridden version of 'helperMethodPublic'
I think it is because of what Jeff said.
Try this - setting up an expectation just as any other mocked method:
SomeClass someClassMock = PowerMock.createPartialMock(SomeClass.class,
"helperMethodPublic");
EasyMock.expect(someClassMock.helperMethodPublic(param1, param2)).
andReturn(returnObject);
PowerMock.replayAll();
I would guess this is because your "helperMethodPublic" is not a private method (as in PowerMock.expectPrivate). PowerMock is a framework that extends other mocking frameworks to add things such as mocking private and static methods (which JMock, Mockito, etc don't handle). Doing a partial mock of public methods should be something your underlying mock framework handles.

Categories

Resources