Mockito mock with constructor parameter - testing

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

Related

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.

Tweak jackson polymorphic deserialization

I have a simple polymorphic model like this
public class Foo {
private Bar bar1;
private Bar bar2;
public Bar getBar1() {
return bar1;
}
public Bar getBar2() {
return bar2;
}
public void setBar1(Bar bar1) {
this.bar1 = bar1;
}
public void setBar2(Bar bar2) {
this.bar2 = bar2;
}
}
#JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "#type")
public class Bar {
}
public class BarExpression extends Bar {
private String expression;
public String getExpression() {
return expression;
}
#JsonIgnore
public Object getValue() {
return null;
}
public void setExpression(String expression) {
this.expression = expression;
}
}
public class BarLiteral extends Bar {
private String value;
private String type;
public String getType() {
return type;
}
public Object getValue() {
return value;
}
public void setType(String type) {
this.type = type;
}
public void setValue(String value) {
this.value = value;
}
}
Serializing a simple example like this
public void run() throws Exception {
Foo foo;
BarLiteral bar1;
BarExpression bar2;
//
foo = new Foo();
bar1 = new BarLiteral();
bar1.setType("java.lang.String");
bar1.setValue("gnu");
foo.setBar1(bar1);
bar2 = new BarExpression();
bar2.setExpression("bean.property * 2");
foo.setBar2(bar2);
//
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
StringWriter w = new StringWriter();
mapper.writeValue(w, foo);
System.out.println(w.toString());
}
gives the expected result:
{
"bar1" : {
"#type" : "de.mit.jackson.BarLiteral",
"value" : "gnu",
"type" : "java.lang.String"
},
"bar2" : {
"#type" : "de.mit.jackson.BarExpression",
"expression" : "bean.property * 2"
}
}
The question is now: I want to improve user experience when handwriting this "DSL" by supporting "primitive shortcuts" for the typed "Bar..." classes like this
{
"bar1" : "gnu",
"bar2" : "#{bean.property * 2}"
}
The solution that came closest was using a converter on Foo#bar1 and Foo#bar2, checking for either String or "Bar" input, but this solution requires decoration of every attribute definition.
Creating a deserializer with a comparable behavior did not work, as the #JsonTypeInfo is not compatible in the sense that i can have a #JsonDeserialize implementation that will check for a String event and then delegate to the standard #JsonTypeInfo process. The #JsonTypeInfo standard will check only for the #type and then delegate back to the (subtype) deserializer which is again my wrapper implementation.
The required process is
if input event is string {
parse and return string input
} else {
activate #type parsing delegate;
after #type parsing activate standard BeanDeserializer
(**not** my implementation)
}
Is there another hook i am missing?

Passing complex navigation parameters with MvvmCross ShowViewModel

My complex type wouldn't pass from Show to Init method even with configured MvxJsonNavigationSerializer as specified here Custom types in Navigation parameters in v3
public class A
{
public string String1 {get;set;}
public string String2 {get;set;}
public B ComplexObject1 {get;set;}
}
public class B
{
public double Double1 {get;set;}
public double Double2 {get;set;}
}
When I pass instance of object A to ShowViewModel method I receive this object with String1 & String2 deserialized correctly but CopmlexObject1 is null.
How to deal with complex object MvvmCross serialization?
I believe there may be some gremlins in that previous answer - will log as an issue :/
There are other possible routes to achieve this type of complex serializable object navigation still using Json and overriding parts of the framework, but actually I think that it might be better to just use your own BaseViewModel's to do serialization and deserialization - e.g. use serialization code like:
public class BaseViewModel
: MvxViewModel
{
private const string ParameterName = "parameter";
protected void ShowViewModel<TViewModel>(object parameter)
where TViewModel : IMvxViewModel
{
var text = Mvx.Resolve<IMvxJsonConverter>().SerializeObject(parameter);
base.ShowViewModel<TViewModel>(new Dictionary<string, string>()
{
{ParameterName, text}
});
}
}
with deserialization like:
public abstract class BaseViewModel<TInit>
: MvxViewModel
{
public void Init(string parameter)
{
var deserialized = Mvx.Resolve<IMvxJsonConverter>().DeserializeObject<TInit>(parameter);
RealInit(deserialized);
}
protected abstract void RealInit(TInit parameter);
}
then a viewModel like this:
public class FirstViewModel
: BaseViewModel
{
public IMvxCommand Go
{
get
{
return new MvxCommand(() =>
{
var parameter = new A()
{
String1 = "Hello",
String2 = "World",
ComplexObject = new B()
{
Double1 = 42.0,
Double2 = -1
}
};
ShowViewModel<SecondViewModel>(parameter);
});
}
}
}
can navigate to something like:
public class SecondViewModel
: BaseViewModel<A>
{
public A A { get; set; }
protected override void RealInit(A parameter)
{
A = parameter;
}
}
A small addition to Stuart's answer to add type safety:
public class BaseViewModel: MvxViewModel {
protected bool ShowViewModel<TViewModel, TInit>(TInit parameter) where TViewModel: BaseViewModel<TInit> {
var text = Mvx.Resolve<IMvxJsonConverter>().SerializeObject(parameter);
return base.ShowViewModel<TViewModel>(new Dictionary<string, string> { {"parameter", text} });
}
}
public abstract class BaseViewModel<TInit> : BaseViewModel {
public void Init(string parameter)
{
var deserialized = Mvx.Resolve<IMvxJsonConverter>().DeserializeObject<TInit>(parameter);
RealInit(deserialized);
}
protected abstract void RealInit(TInit parameter);
}
ShowViewModel method now takes the same parameter type that the RealInit method instead of an object type. Also, BaseViewModel<TInit> inherits from BaseViewModel so their instances can also call the new ShowViewModel method.
The only drawback is that you have to explicitly specify the parameter type in the call like this:
ShowViewModel<StoreInfoViewModel, Store>(store);

proguard copying methods in interface

after decompiling my interface i found out that proguard duplicated my implemented method in the upper level interface that is somehow a class on its own right.
here's how my interface looks like after obfuscation (note that proguard even added the annotation from the implementation)
package com.company.project.f.a.a;
import java.util.List;
import org.apache.log4j.Logger;
#Component(value="ServiceImpl")
public class a
{
public b a(int i)
{
if((i = b.a(i)) != null)
{
if(i.size() == 0)
{
a_.fatal("It is expected at least one record.");
return null;
} else
{
return (b)i.get(0);
}
} else
{
return null;
}
}
public a()
{
a_ = Logger.getLogger(getClass());
}
public com.company.project.b.a.a a()
{
return b;
}
public void a(com.company.project.b.a.a a1)
{
b = a1;
}
private com.company.project.b.a.a b;
Logger a_;
}
same issue happened with the class below (proguard transforming the interface into a class with the same component name)
#Component("testDao")
public class TestDaoImpl implements TestDao {
#Override
public void testing() {
// TODO Auto-generated method stub
}
solved it :
according to mr eric lafortune , the optimizer is merging interface and class .
so i used
-dontoptimize

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