How do I mock a static method call from a nother static method in the same class? - powermock

I have a utilities class wherein one static method calls another. I want to mock the called method but not the target method. Does anyone have an example?
I've got:
#RunWith(PowerMockRunner.class)
#PrepareForTest({SubjectUnderTest.class})
public class SubjectUnderTestTest {
...
SubjectUnderTest testTarget = PowerMockito.mock(SubjectUnderTest.class, Mockito.CALLS_REAL_METHODS);

Starting from the docs, with some minor tweaks, you can either mock or spy the static method, depending on what you need (spying seems a bit less verbose but has different syntax). You can find below a sample for both, based on PowerMockito 1.7.3 & Mockito 1.10.19.
Given the following simple class with the required 2 static methods:
public class ClassWithStaticMethods {
public static String doSomething() {
throw new UnsupportedOperationException("Nope!");
}
public static String callDoSomething() {
return doSomething();
}
}
You can do something like:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.powermock.api.mockito.PowerMockito.*;
// prep for the magic show
#RunWith(PowerMockRunner.class)
#PrepareForTest(ClassWithStaticMethods.class)
public class ClassWithStaticMethodsTest {
#Test
public void shouldMockStaticMethod() {
// enable static mocking
mockStatic(ClassWithStaticMethods.class);
// mock the desired method
when(ClassWithStaticMethods.doSomething()).thenReturn("Did something!");
// can't use Mockito.CALLS_REAL_METHODS, so work around it
when(ClassWithStaticMethods.callDoSomething()).thenCallRealMethod();
// validate results
assertThat(ClassWithStaticMethods.callDoSomething(), is("Did something!"));
}
#Test
public void shouldSpyStaticMethod() throws Exception {
// enable static spying
spy(ClassWithStaticMethods.class);
// mock the desired method - pay attention to the different syntax
doReturn("Did something!").when(ClassWithStaticMethods.class, "doSomething");
// validate
assertThat(ClassWithStaticMethods.callDoSomething(), is("Did something!"));
}
}

Related

How to mock UUID.randomUuid() and System.currentTimeMillis() without PowerMock?

I am improving my code coverage, and I am using Sonar to compute it.
But Sonar and PowerMock are not very compatible. I was wondering if there is another way to mock UUID.randomUUID() and System.currentTimeMillis() methods without using PowerMock?
I know that PowerMock can introduce difficulties, but I'm not aware of any reason why SonarQube would be incompatible with it.
In any case, recent versions of Mockito can mock static methods (although I haven't used this yet): https://www.baeldung.com/mockito-mock-static-methods .
As rightly noted by #Augusto, one should introduce dependencies instead of relying on static method calls. Then you won't need powermock at all.
Assuming your tools are JUnit5, assertj and mockito. An example goes like this:
// -- production code --
import java.util.UUID;
import java.util.function.Supplier;
public class ProductionCode {
private final Supplier<String> idSupplier;
private final Supplier<Long> clock;
// #VisibleForTesting
ProductionCode(Supplier<String> idSupplier, Supplier<Long> clock) {
this.idSupplier = idSupplier;
this.clock = clock;
}
public ProductionCode() {
this(() -> UUID.randomUUID().toString(), System::currentTimeMillis);
}
public String methodUnderTest() {
return String.format("%s -- %d", idSupplier.get(), clock.get());
}
}
// -- test code without mocking
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
public class Tests {
#Test
void methodUnderTest_shouldSeparateByDoubleDashRandomIdAndCurrentTime() {
ProductionCode objectUnderTest = new ProductionCode(() -> "id", () -> 1234L);
String s = objectUnderTest.methodUnderTest();
assertThat(s).isEqualTo("id -- 1234");
}
}
// -- test code (mockito) --
import static org.assertj.core.api.Assertions.assertThat;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
public class Tests {
private final Supplier<String> idSupplier = Mockito.mock(Supplier.class);
private final Supplier<Long> clock = Mockito.mock(Supplier.class);
private final ProductionCode objectUnderTest = new ProductionCode(idSupplier, clock);
#Test
void methodUnderTest_shouldSeparateRandomIdAndCurrentTimeByDoubleDash() {
Mockito.when(idSupplier.get()).thenReturn("id");
Mockito.when(clock.get()).thenReturn(1234L);
String s = objectUnderTest.methodUnderTest();
assertThat(s).isEqualTo("id -- 1234");
}
}

How to create mock instance of Autowired component in Vert.x

I am trying to create mock instance of the class which is autowired inside Verticle but I am getting it as a null. For synchronous code the way which works is looking not useful for Vert.x.
Verticle is:
#Component
public class MyVerticle extends AbstractVerticle{
#Autowired
private ServiceExecutor serviceExecutor;
#Override
public void start() throws Exception {
super.start();
vertx.eventBus().<String>consumer("address.xyz").handler(handleRequest());
}
private Handler<Message<String>> handleRequest() {
return msg -> {
getSomeData(msg.body().toString())
.setHandler(ar -> {
if(ar.succeeded()){
msg.reply(ar.result());
}else{
msg.reply(ar.cause().getMessage());
}
});
};
}
private Future<String> getSomeData(String inputJson) {
Promise<String> promise = Promise.promise();
String data = serviceExecutor.executeSomeService(inputJson); // Getting NPE here. serviceExecutor is coming as null when trying to create mock of it using Mockito.when.
promise.complete(data);
return promise.future();
}
}
Dependent component is:
#Component
public class ServiceExecutor {
public String executeSomeService(String input){
return "Returning Data";
}
}
Test case is:
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import io.vertx.core.Vertx;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
#RunWith(VertxUnitRunner.class)
public class MyVerticleTest {
#Mock
private ServiceExecutor serviceExecutor;
private Vertx vertx;
#Before
public void setup(TestContext ctx){
MockitoAnnotations.initMocks(this);
Async async = ctx.async();
this.vertx = Vertx.vertx();
vertx.deployVerticle(MyVerticle.class.getName(), h -> {
if(h.succeeded()){
async.complete();
}else{
ctx.fail();
}
});
}
#Test
public void test_consumption(TestContext ctx) {
Async async = ctx.async();
when(serviceExecutor.executeSomeService(Mockito.anyString())).thenReturn("Returning Data");
vertx.eventBus().request("address.xyz","message", h ->{
if(h.succeeded()){
ctx.assertEquals("Returning Data",h.result().body().toString());
async.complete();
}else{
ctx.fail(h.cause());
}
});
}
}
Above Test Case works well if I don't use autowired instance to call a method to get the date. But if used it (which I must do to get the data), it is giving NPE at MyVerticle->getSomeData() method when trying to use serviceExecutor object as a mock. This approach works very well for Synchronous code flow but for Vert.x looks like it won't help. So need help here to mock the autowired instance serviceExecutor inside Verticle.
Add a constructor in your MyVerticle
public MyVerticle(ApplicationContext context) {
context.getAutowireCapableBeanFactory().autowireBean(this);
}
and deploy your verticle something like vertx.deployVerticle(new MyVerticle(context),...
I have application context while deploying the verticle and thats what I am passing in the constructor. Check if this works for you.

Calling local class

I'm trying to call a static method from a class called "JSON", however the import I'm doing already has this method. How can I call a local class?
I've tried this:
mypackage.subpackage.JSON.encode(param1)
In C # the above would work, but I do not know why in ActionScript below does not work.
import flash.utils.ByteArray;
public class Package extends ByteArray
{
public function writeJsonObject(param1:Object) : void
{
this.writeUTF(JSON.encode(param1));
}
}
I get this error:
Error: 1061: Call to a possibly undefined method decode through a reference with static type Class
Try using JSON.stringify()
import flash.utils.ByteArray;
public class MyClass extends ByteArray
{
public function writeJsonObject(param1:Object) : void
{
this.writeUTF(JSON.stringify(param1));
}
}
Reference: https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/JSON.html
Also worth noting the difference between writeUTF and writeUTFBytes to understand exactly what's getting written to your ByteArray

JUNIT test case for void method

I have a method whose JUnit test case I have to write. It just calls the main processing method of the project and does nothing else. Also, the main processing method also has return type as void.
How shall I test such a "method1"?
public void method1() {
obj1.mainProcessingMethod():
}
Given a class:
public class A {
private Obj obj1;
public void method1() {
obj1.mainProcessingMethod();
}
public void setObj1(Obj obj1) {
this.obj1 = obj1;
}
}
In test for this class, the only thing to test would be verification whether method obj1.mainProcessingMethod() was invoked exactly once.
You can achieve this with Mockito.
import org.junit.Test;
import org.mockito.Mockito;
public class ATest {
private Obj obj1 = Mockito.mock(Obj.class);
private A a = new A();
#Test
public void testMethod1() {
a.setObj1(obj1);
a.method1();
Mockito.verify(obj1).mainProcessingMethod();
}
}
Here you create a mock object for class Obj, inject it into instance of A, and later use mock object to check which method invocations it recorded.
Inside the test you need to verify that the method mainProcessingMethod(): is called on the object obj1.
you can use something like
Mockito.verify(yourMockObject);

Mocking a class in PowerMock

I am using PowerMocking for JUNIT and Iam new to PowerMock.
I want to mock one class which is non static.
The class scenario goes as follows.
public class Export extends MyUtil implements ExportFormatting<DeptSummaryByDCDTO, LmReportsInputDTO>{
public String createPDF(List<DeptSummaryByDCDTO> summaryDtoList, LmReportsInputDTO inputDto){
}
public String createPDF(Map<String, DeptSummaryByDCDTO> paramMap,
LmReportsInputDTO paramK) {
}
}
The calling class is as follows.
public static Response getMultiplePackSku{
filePath = new Export(inputDto).createPDF(resultList,null);
}
The Question is,
I am trying to test the above class using powermock.
Can anybody tell how to mock the line filePath.....
You need to first mock the constructor and return an Export mock. On the returned mock you need to record the call to createPDF. The tricky part is the constructor mocking. I'll give you an example, hopefully you'll get all of it:
#RunWith(PowerMockRunner.class) // This annotation is for using PowerMock
#PrepareForTest(Export.class) // This annotation is for mocking the Export constructor
public class MyTests {
private mockExport;
#Before
public void setUp () {
// Create the mock
mockExport = PowerMock.createMock(Export.class)
}
#Test
public void testWithConstructor() {
SomeDtoClass inputDto = PowerMock.createMock(SomeDtoClass.class);
PowerMock.expectNew(Export.class, inputDto).andReturn(mockExport);
PowerMock.replay(mockExport, Export.class);
expect(mockExport.createPDF(resultList, null);
// Run the tested method.
}
}
Here is a description of how to mock a constructor call: MockConstructor