Jmockit #Mocked return empty object on lombok #builder - jmockit

I am using Jmockit for my Junit test.
When I'm testing a function which uses lombok's builder.build(), it returns an instance with empty values.
I've also tried to use #Injectable and #Capturing, both gave me the same result.
#Test
public void test_updateStatusFromResponse_success_payment_result(#Mocked MyObject myObject) {
myClass.myFunction("paraA","paraB");
}
public class myClass{
public void myFunction(String paraA, String paraB){
MyObject myObject = MyObject.builder.
StringA(paraA).
StringB(paraB).
build();
//myObject's both StringA and StringB is null
}
}
#Builder
#Getter
public class MyObject {
private final String StringA;
private final String StringB;
}

Related

how to make reference type for string enum in kotlin and jacoco coverage testable

Converted a java class into kotlin in Android app, the jacoco coverage starts to show 0 coverage on a compiler generated function, which is not access able. Other ones seem fine in the report.
How to make reference type for string enum in kotlin and jacoco coverage testable
java code:
public final class Message {
private Message() { }
public static class MessageAction {
public static final String OPEN = "open";
public static final String VIEW_ALL = "view_all";
#Retention(RetentionPolicy.SOURCE)
#StringDef({OPEN, VIEW_ALL})
public #interface Action { }
public String mAction;
public MessageAction(#Action String action) {
this.mAction = action;
}
public String getMessageAction() {
return this.mAction;
}
}
}
in kotlin;
import androidx.annotation.StringDef
class Message private constructor() {
class MessageAction(#param:Action var messageAction: String) {
#kotlin.annotation.Retention(AnnotationRetention.SOURCE)
#StringDef(OPEN, VIEW_ALL)
annotation class Action
companion object {
const val OPEN = "open"
const val VIEW_ALL = "view_all"
}
}
}
this is sample of how it is used in java code:
public static void doSomeThing(#Nullable String message, #Message.MessageAction.Action String action) {
...
}
and the test:
#Test
public void test_messageAction() {
String testAction = "open";
Message.MessageAction action = new Message.MessageAction(Message.MessageAction.OPEN);
assertEquals(testAction, action.getMessageAction());
}
the jacoco test coverage result shows 0 covergate on the function setMessageAction(#NotNull String var1) which is in the decompiled java code.
And it is not visible from the code's autocomplete hint.
the kotlin decompiled java code:
public final class Message {
private Message() {
}
#Metadata( ...... )
public static final class MessageAction {
#NotNull
private String messageAction;
#NotNull
public static final String OPEN = "open";
#NotNull
public static final String VIEW_ALL = "view_all";
public static final Message.MessageAction.Companion Companion = new Message.MessageAction.Companion((DefaultConstructorMarker) null);
#NotNull
public final String getMessageAction() {
return this.messageAction;
}
public final void setMessageAction(#NotNull String var1) { //<=== coverage result shows it is not called
Intrinsics.checkNotNullParameter(var1, "<set-?>");
this.messageAction = var1;
}
public MessageAction(#NotNull String messageAction) {
Intrinsics.checkNotNullParameter(messageAction, "messageAction");
super();
this.messageAction = messageAction;
}
#Retention(AnnotationRetention.SOURCE)
#java.lang.annotation.Retention(RetentionPolicy.SOURCE)
#Metadata( ...... )
public #interface Action {
}
#Metadata( ...... )
public static final class Companion {
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
}
adding #JvmField resolves it
class MessageAction(#param:Action messageAction: String) {
#kotlin.annotation.Retention(AnnotationRetention.SOURCE)
#StringDef(OPEN, VIEW_ALL, CLEAR, TOUCH3D, PLAY, PAUSE, DISMISSED)
annotation class Action
#JvmField
var messageAction: String = messageAction
companion object {
const val OPEN = "open"
const val VIEW_ALL = "view_all"
}
}

Mockito mock with constructor parameter

I am using mockito 1.9.5 and wanting to test a class that i have posted on github.
The issue is that I need to mock the getStringFromExternalSources method.
MyClass code:
public class MyClass {
String a,b,c;
public MyClass(String a, String b, String c) {
this.a = a;
this.b = b;
this.c = c;
}
public String executeLogic (String d) {
return a + b + c + d;
}
public String getStringFromExternalSources (){
return "i got it from some place else";
}
}
My current test:
#RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
#Test
public void MyClassTest() {
MyClass mc = Mockito.spy(new MyClass("a","b","c") );
Mockito.doReturn("mock").when(mc.executeLogic("real"));
Mockito.doReturn("externalString").when(mc.getStringFromExternalSources());
System.out.println(mc.executeLogic("real"));
}
}
Any pointers ?
You can mock any method using when().thenReturn() construct.
Example:
MyClass mc = Mockito.spy(new MyClass("a","b","c"));
when(mc.getStringFromExternalSource()).thenReturn("I got it from there!!");
So whenever the method 'getStringFromExternalSource()' is invoked for the mocked object mc then it will return "I got it from there!!".
if you want to Test class with different parameters then you can use #Parameters annotation to provide parameters to the class in conjunction with Parameterized runner and mention the parameters in a public static method with #Paramters annotation. A rough example would be:
#RunWith(Parameterized.class)
class SomeTestClass{
#Mock
SomeTestClass mSomeTestClassInstance;
#Parameters
public static Object provideParameters() {
Object[] objects = new Object[]{
0,
0,
2
};
return objects;
}
public SomeTestClass(Object argument1){
mArgument1 = argument1;
}
#Test
public void testSomeMethod{
Object returnValue = mSomeTestClassInstance.testSomeMethod(mArgument1);
assertequals(mArgument1,returnValue)
}
}
How to mock getStringFromExternalSources method:
public class MyClassTest {
#Test
public void MyClassTest() {
MyClass mc = mock(MyClass.class);
when(mc.executeLogic("real").thenReturn("mock");
when(mc.getStringFromExternalSources().thenReturn("externalString");
System.out.println(mc.executeLogic("real"));
}
}

Mapping DTO with final members in MapStruct

is there a way to map a DTO using MatStruct which have a few final data members as well and cannot have a default constructor , like :
public class TestDto {
private final String testName;
private int id;
private String testCase;
public TestDto(String testName) {
this.testName = testName;
}
public String getTestName() {
return testName;
}
public int getId() {
return id;
}
public String getTestCase() {
return testCase;
}
public void setId(int id) {
this.id = id;
}
public void setTestCase(String testCase) {
this.testCase = testCase;
}
}
please suggest how could this DTO be mapped using MapStruct.
You can use #ObjectFactory that would construct an instance of your DTO.
For example:
#Mapper
public interface MyMapper {
#ObjectFactory
default TestDto create() {
return new TestDto("My Test Name");
}
//the rest of the mappings
}
You can also enhance the #ObjectFactory to accept the source parameter, that you can use to construct the TestDto. You can even use a #Context as an Object Factory.
NB: You don't have to put the #ObjectFactory method in the same Mapper, or even a MapStruct #Mapper. You can put it in any class (or make it static) and then #Mapper(uses = MyFactory.class)

How to use JMockit MockUp for default interface method

Trying to apply a MockUp on a Java 8 default interface method, and JMockit tells me that method cannot be found. This has been tried with JMockit 1.15, 1.19, and 1.25. Here's a very simple use case:
#RunWith(JMockit.class)
public class TestTest {
public interface MyInterface {
default void foo(int f) {
bar(String.valueOf(f));
}
void bar(String s);
}
public class MyClass implements MyInterface {
public void bar(String s) {
System.out.println(s);
}
}
#Test
public void testtest() throws Exception {
new MockUp<MyClass>() {
#Mock
void foo(int i) {
System.out.println("MOCKMOCK " + (i*2));
}
#Mock
void bar(String s) {
System.out.println("MOCK " + s);
}
};
MyClass baz = new MyClass();
baz.foo(5);
baz.bar("Hello world");
}
}
This gets me the error
java.lang.IllegalArgumentException: Matching real methods not found for the following mocks:
com.example.dcsohl.TestTest$1#foo(int)
at com.example.dcsohl.TestTest$1.<init>(TestTest.java:29)
at com.example.dcsohl.TestTest.testtest(TestTest.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
How can we #Mock this method?
Slightly modifying your use case to return strings instead of printing to standard out the following solution will work.
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import mockit.Expectations;
public class TestTest {
public interface MyInterface {
default String foo(int f) {
return bar(String.valueOf(f));
}
String bar(String s);
}
public class MyClass implements MyInterface {
public String bar(String s) {
return s;
}
}
#Test
public void testtest() throws Exception {
MyClass baz = new MyClass();
new Expectations(MyClass.class) {{
baz.foo(anyInt); result = "FOOMOCK";
baz.bar(anyString); result = "BARMOCK";
}};
assertEquals(baz.foo(5), "FOOMOCK");
assertEquals(baz.bar("Hello world"), "BARMOCK");
}
}
There are many useful examples of how to mock out interfaces with method bodies (ie default or static methods) outlined in the examples section on the jmockit github repository.
Use #Mocked instead of a MockUp, it supports default methods.

Jackson configuration to write enum as object

When I try to serialize and deserialize a Set<ClassA<?>> of generic objects that look as follows:
public class ClassA<T> {
private ClassB datum;
private T value;
...
}
If that T happens to be an enum, it gets written as a String value. This is fine for serialization, but when I deserialize, it's not possible to know if the String value is an enum or not. Jackson then turns the resulting object into a String and you get a ClassA<String> instead of ClassA<SomeEnumType>.
Is there a configuration in Jackson to have it create some hints that the value is an enum? Or perhaps turn the enum into a JSON object rather then a string value?
Is there a configuration in Jackson to have it create some hints that the value is an enum?
It's possible to deserialize to an enum instance from a matching JSON string value. Or is this somehow not applicable to your situation?
Here is an example.
import java.util.Set;
import java.util.TreeSet;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.type.TypeFactory;
public class JacksonFoo
{
public static void main(String[] args) throws Exception
{
ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);
String myEnumJson = mapper.writeValueAsString(MyEnum.MyEnum1);
System.out.println(myEnumJson);
MyEnum myEnum = mapper.readValue(myEnumJson, MyEnum.class);
System.out.println(myEnum);
Set<ClassA<MyEnum>> set = new TreeSet<ClassA<MyEnum>>();
set.add(new ClassA<MyEnum>(new ClassB("bValue7"), MyEnum.MyEnum1));
set.add(new ClassA<MyEnum>(new ClassB("bValue8"), MyEnum.MyEnum2));
String setJson = mapper.writeValueAsString(set);
System.out.println(setJson);
TypeFactory typeFactory = TypeFactory.defaultInstance();
Set<ClassA<MyEnum>> setCopy = mapper.readValue(setJson,
typeFactory.constructCollectionType(Set.class,
typeFactory.constructParametricType(ClassA.class, MyEnum.class)));
System.out.println(setCopy);
}
}
class ClassA<T> implements Comparable<ClassA<T>>
{
ClassB datum;
T value;
ClassA()
{
}
ClassA(ClassB datum, T value)
{
this.datum = datum;
this.value = value;
}
#Override
public int compareTo(ClassA<T> o)
{
return 42;
}
#Override
public String toString()
{
return String.format("ClassA: datum=%s, value=%s", datum, value);
}
}
class ClassB
{
String bValue;
ClassB()
{
}
ClassB(String bValue)
{
this.bValue = bValue;
}
#Override
public String toString()
{
return String.format("ClassB: bValue=%s", bValue);
}
}
enum MyEnum
{
MyEnum1("myEnum1", 1), MyEnum2("myEnum2", 2);
String name;
int id;
MyEnum(String name, int id)
{
this.name = name;
this.id = id;
}
}
Output:
"MyEnum1"
MyEnum1
[{"datum":{"bValue":"bValue7"},"value":"MyEnum1"},{"datum":{"bValue":"bValue8"},"value":"MyEnum2"}]
[ClassA: datum=ClassB: bValue=bValue7, value=MyEnum1, ClassA: datum=ClassB: bValue=bValue8, value=MyEnum2]
If for some reason it's necessary to have enums serialized as POJOs, then it appears custom serialization processing is required. Serializing enums with Jackson