How can we instantiate the constructor in Akka Actor? - java

I am writing unit tests for my akka actor classes. a field is being declared in abstract parent class and instantiated inside its constructor. During test case execution of child class that field is showing null. So how to instantiate the field from the test class.
Note: I am using partial Mocking also in testNG classes.
public abstract class ParentClass extends UntypedActor {
protected RestTemplate restTemplate;
protected ObjectMapper objMapper;
public ParentClass () {
super();
restTemplate = new RestTemplate();
objMapper = new ObjectMapper();
}
}
public class ChildClass extends ParentClass{
public ChildClass () {
super();
}
public void invoke(String json) throws Exception {
BeanClass bean = objMapper.readValue(json, Bean.class);
}
public String getJsonResponse(String json){
sysout("Get");
return "response";
}
}
public class ChildClassUnitTest {
#BeforeTest
public void setUp() throws Exception{
actorMock = PowerMock.createPartialMock(ChildClass.class,"getJsonResponse");
actorMock.getJsonResponse("req");
PowerMock.expectLastCall().andReturn("resp").anyTimes();
PowerMock.replay(actorMock);
}
#Test
public void testInvokePos() throws Exception{
ResponseClass response=actorMock.invoke("req");
System.out.println(response);
}
}

I am not known to json and I can only help with java code.
Please look at code below.
And my instance fields are initialized properly. They are not null. So I don't see any problem with your code atleast with what you have posted. Need to visit your UntypedActor class.
class ClassA
{
String x;
public ClassA ()
{
x = "Java";
}
}
abstract class ParentClass extends ClassA{
protected String restTemplate;
protected Integer objMapper;
public ParentClass () {
super();
restTemplate = " Language";
objMapper = 1;
}
}
class ChildClass extends ParentClass{
public ChildClass () {
super();
}
}
class HelloWorld
{
public static void main (String args[] )
{
ChildClass cc = new ChildClass ();
System.out.println ( cc.x + cc.restTemplate + cc.objMapper );
}
}
Output for the code is as expected
Java Language1

Related

How to make an internal method call check

How can I use Mockito to check a call inside a method to another method of another class?
public class FirstClass {
private SecondClass secondClass = new SecondClass();
public void sum() {
secondClass.sum_2(1, 2);
}
}
I need to check that the second Class.sum_2() method is called with parameters
MyTest:
public class FirstTest {
FirstClass firstClass = new FirstClass();
SecondClass secondClass = Mockito.spy(SecondClass.class);
#Test
public void first() {
firstClass.sum();
Mockito.verify(secondClass).sum_2(eq(1), eq(2));
}
}
But answer:
Wanted but not invoked:
secondClass.sum_2(1, 2);
-> at FirstTest.first(FirstTest.java:14)
Actually, there were zero interactions with this mock.
There are a few possibilities how to solve this problem. As I mentioned in my comment, the most common approach is to create a constructor in FirstClass with a SecondClass parameter, so that you can inject an instance from outside.
Constructor injection
public class FirstClass {
private SecondClass secondClass;
public FirstClass(SecondClass secondClass) {
this.secondClass = secondClass;
}
public void sum() {
secondClass.sum_2(1, 2);
}
}
public class FirstTest {
FirstClass firstClass;
SecondClass secondClass;
#Before
public void setup() {
secondClass = Mockito.spy(new SecondClass());
firstClass = new FirstClass(secondClass);
}
#Test
public void first() {
firstClass.sum();
Mockito.verify(secondClass).sum_2(eq(1), eq(2));
}
}
If you can not create a constructor, you could add a setter and inject your instance that way.
Setter injection
public class FirstClass {
private SecondClass secondClass;
public void setSecondClass(SecondClass secondClass) {
this.secondClass = secondClass;
}
public void sum() {
secondClass.sum_2(1, 2);
}
}
public class FirstTest {
FirstClass firstClass;
SecondClass secondClass;
#Before
public void setup() {
secondClass = Mockito.spy(new SecondClass());
firstClass = new FirstClass();
firstClass.setSecondClass(secondClass);
}
#Test
public void first() {
firstClass.sum();
Mockito.verify(secondClass).sum_2(eq(1), eq(2));
}
}
And if you really, really can't modify FirstClass at all, you have to resort to using reflection.
With reflection
public class FirstClass {
private SecondClass secondClass;
public void sum() {
secondClass.sum_2(1, 2);
}
}
public class FirstTest {
FirstClass firstClass;
SecondClass secondClass;
#Before
public void setup() throws NoSuchFieldException, IllegalAccessException {
secondClass = Mockito.spy(new SecondClass());
firstClass = new FirstClass();
Field field = FirstClass.class.getDeclaredField("secondClass");
field.setAccessible(true);
field.set(firstClass, secondClass);
}
#Test
public void first() {
firstClass.sum();
Mockito.verify(secondClass).sum_2(eq(1), eq(2));
}
}

How to invoke child class method from parent class through reflection

I want to create a menu which should be populated by arbitrary methods, which are marked by an annotation. The methods should be invoked from inside the base class. Unfortunately 'java.lang.ClassCastException' is thrown since the method.invoke function expects an object which is instance of the child class. But i only get the base class.
Here is what i tried so far :
public abstract Class BaseClass{
private void invokeSomeMethod(){
final Method[] methods= getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(MenuFunction.class)) {
MenuFunction menuFunction = method.getAnnotation(MenuFunction.class);
menuFunction.invoke(this); //Throws 'java.lang.ClassCastException'
}
}
}
#Retention(RetentionPolicy.RUNTIME)
#Target({ METHOD })
public #interface MenuFunction {
String Label();
}
}
public Class ChildClass extends BaseClass{
#MenuFunction(Label = "First method")
public void setHigh(){
//Arbitrary function
}
#MenuFunction(Label = "Another method")
public void setLow(){
//Do something
}
}
I guess what you want to do is this:
public abstract class BaseClass {
public void invokeSomeMethod() throws InvocationTargetException, IllegalAccessException {
final Method[] methods = getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(MenuFunction.class)) {
MenuFunction menuFunction = method.getAnnotation(MenuFunction.class);
method.invoke(this); //invoke method here'
}
}
}
}
public class ChildClass extends BaseClass{
#MenuFunction(Label = "hello")
public void hello() {
System.out.println("hello");
}
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
new ChildClass().invokeSomeMethod();
}
}
Result:
hello

Mock object of super class in subclass using EasyMock

I have a class to be tested which is like this:
public class MainClass extends BaseClass {
public static int variableToBeAsserted= 0;
MainClass(ConfigClass config) {
super(config);
}
public void myMethod() {
List list = objectOfClass1inSuperClass.operation(objectOfClass2inSuperClass.method())
while(methodInSuperClass()) {
// doing operations with 'list'
variableToBeAsserted++;
}
}
// ..few other methods which I am not going to test.
}
I have suppressed the constructor of my BaseClass and my ConfigClass. Now my test class is like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest(MainClass.class)
public class TestClass {
#Before
public void setUp(){
suppress(constructor(BaseClass.class))
suppress(constructor(ConfigClass.class))
}
#Test
public void testMyMethod(){
MainClass main = new MainClass(new ConfigClass(""));
List list1= new ArrayList();
test1.add("somevalues");
Class1inSuperClass ob1 = PowerMock.createMock(Class1inSuperClass.class);
Class2inSuperClass ob2 = PowerMock.createMock(Class2inSuperClass.class);
EasyMock.expect(ob2.method()).andReturn(getClass());
EasyMock.expect(ob1.operation(getClass())).andReturn(list1);
PowerMock.replayAll();
main.myMethod();
Assert.assertEquals(expectedValue, main.variableToBeAsserted);
}
}
Now I don't know why but my test case fails with a NullPointerException.
It tries to access objectofClass1inSuperClass and fails. I thought this will mock it. But it does not get mocked.
EDIT: I am writing only the test and I cannot change anything in BaseClass. However I have the option to modify the MainClass.
You have two ways to inject mock object to the object under the test.
Manually via WhiteBox
#RunWith(PowerMockRunner.class)
#PrepareForTest(MainClass.class)
public class WhiteBoxApproachTestClass {
#Before
public void setUp() throws Exception {
suppress(constructor(BaseClass.class));
}
#Test
public void testMyMethod() {
MainClass main = new MainClass(createMock(ConfigClass.class));
List<String> list1 = new ArrayList<>();
list1.add("somevalues");
Class1inSuperClass ob1 = createMock(Class1inSuperClass.class);
Class2inSuperClass ob2 = createMock(Class2inSuperClass.class);
expect(ob2.method()).andReturn(getClass());
expect(ob1.operation(getClass())).andReturn(list1);
Whitebox.setInternalState(main, "objectOfClass1inSuperClass", ob1);
Whitebox.setInternalState(main, "objectOfClass2inSuperClass", ob2);
replayAll();
main.myMethod();
assertThat(MainClass.variableToBeAsserted).isEqualTo(5);
}
}
And via #TestSubject (http://easymock.org/user-guide.html#mocking-annotations)
#RunWith(PowerMockRunner.class)
#PrepareForTest(MainClass.class)
public class TestSubjectApproachTestClass {
#Mock(fieldName = "objectOfClass1inSuperClass")
private Class1inSuperClass ob1;
#Mock(fieldName = "objectOfClass2inSuperClass")
private Class2inSuperClass ob2;
#TestSubject
private final MainClass main = new MainClass(createMock(ConfigClass.class));
#BeforeClass
public static void before() throws Exception {
suppress(constructor(BaseClass.class));
}
#Test
public void testMyMethod() {
List<String> list1= new ArrayList<>();
list1.add("somevalues");
expect(ob2.method()).andReturn(getClass());
expect(ob1.operation(getClass())).andReturn(list1);
EasyMockSupport.injectMocks(main);
replayAll();
main.myMethod();
assertThat(MainClass.variableToBeAsserted).isEqualTo(5);
}
}
Full code you may find here.

Jmockit #Mocked inside a helper class doesn't initialize

If I have the following;
public class ClassA {
public void methodA(){
System.out.println("In ClassA, methodA");
}
}
public class ClassB {
public void methodB(){
}
}
and a junit test of;
#Test
public void testMocked(#Mocked final ClassB mockedB) {
System.out.println("Mocked inline");
new MockUp<ClassA>() {
#Mock
public void methodA() {
System.out.println("Inline mockup, mockedB:" + mockedB);
}
};
ClassA a = new ClassA();
a.methodA();
}
Then when I run the test I get;
Mocked inline
Inline mockup, mockedB:jmockitpractice.ClassB#329b0985
Which is as expected, the classB is Mocked, and an instance is available.
But, if I change this to create a helper class for mocking,
public class MockHelper {
#Mocked ClassB classB;
public void setupMocks(){
new MockUp<ClassA>() {
#Mock
public void methodA(){
System.out.println("In setupMocks, classB:"+classB);
}
};
}
}
and the junit becomes;
#Test
public void testMockedInClass() {
System.out.println("Mocked in helper class");
MockHelper mh = new MockHelper();
mh.setupMocks();
ClassA a = new ClassA();
a.methodA();
}
the result I get is;
Mocked in helper class
In setupMocks, classB:null
classB is not initialized by the #Mocked inside MockHelper
I would like to have all the mocking in a helper class, rather than having to declare all the mocking in the test class.
Any ideas why this doesn't work?
Thanks.
Thanks Dom Farr, the answer was inheritance.
public class MockHelper {
#Mocked
ClassB classB;
public void setupMocks() {
new MockUp<ClassA>() {
#Mock
public void methodA() {
System.out.println("In setupMocks, classB:" + classB);
}
};
}
}
and
public class mockTest extends MockHelper {
#Test
public void testMockedInClass() {
System.out.println("Mocked in helper class");
setupMocks();
ClassA a = new ClassA();
a.methodA();
}
}
As the test class extends the helper, it now works;
Mocked in helper class
In setupMocks, classB:jmockitpractice.ClassB#5d54e317

Using final object in anonymous inner class results in null

I have a method that contains the following code:
public void myMethod(){
final MyDto expectedtDto = new MyDto();
MyRepository reposWithMock = new MyRepository(){
protected MyDao createDao(){
return new MyDao() {
public MyDto someMethod(){
return expectedtDto;
}
};
}
};
reposWithMock.doSomethingWithDao();
}
MyRepository.createDao() is called from the constructor of MyRepository.
MyDao.someMethod() is called from MyRepository.doSomethingWithDao().
However, the MyDao().someMethod() returns null instead of the expectedDto
Any idea why this is?
For clarification, some real working code:
package nl.tests;
public class TestAnon {
static class MyDao {
private int value;
public MyDao(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
static class Repository {
private MyDao dao;
public Repository() {
dao = createDao();
}
protected MyDao createDao(){
return new MyDao( 4 );
}
public MyDao getDao(){
return dao;
}
}
public static void main(String[] args) {
final MyDao testDao = new MyDao(8);
Repository repos = new Repository() {
protected MyDao createDao() {
if ( testDao == null ) {
System.out.println( "Error ");
return new MyDao(0);
}
return testDao;
}
};
System.out.println( "Dao :" + repos.getDao().getValue() );
}
}
This results in :
Error
Dao :0
Some additional information: I currently (have to) work with java 1.4.
My development environment is Rational Application Developer 7.
Addendum, to the given (and accepted answer). For the below code I've made the createDao() method public :
public static void main(final String[] args) {
final MyDao testDao = new MyDao(8);
Repository repos = new Repository() {
public MyDao createDao() {
if ( testDao == null ) {
System.out.println( "Error ");
return new MyDao(0);
}
return testDao;
}
};
System.out.println( "Dao :" + repos.getDao().getValue() );
System.out.println( "Dao :" + repos.createDao().getValue() );
}
Returns:
Error
Dao :0
Dao :8
It fails in Java 1.4 because the field containing the local variable is not yet initialized when the super constructor for Repository is executed.
It works in Java 1.5 and later, because then the field is initialized before the super constructor is called.
In general it is bad style to call methods which may be overridden in subclasses in a constructor, because it leads to this kind of problems.
According to what you provided a quick test outputs MyDto#190d11 or similar. So I bet you left out some important code which is responsible for some variable name hiding.
Test.java
public class Test {
public static void main(String args[]) {
new Test().myMethod();
}
public void myMethod() {
final MyDto expectedtDto = new MyDto();
MyRepository reposWithMock = new MyRepository() {
#Override
protected MyDao createDao() {
return new MyDao() {
#Override
public MyDto someMethod(){
return expectedtDto;
}
};
}
};
reposWithMock.doSomethingWithDao();
}
}
MyDto.java
public class MyDto {}
MyRepository.java
public abstract class MyRepository {
protected abstract MyDao createDao();
public void doSomethingWithDao() {
System.out.println(createDao().someMethod());
}
}
MyDao.java
public abstract class MyDao {
public abstract MyDto someMethod();
}
Make sure you actually override the method you think you do. Your IDE or #Override should help.
Is MyDto a child of MyDao?
Your return a MyDto when the method indicates you return a MyDao.
Maybe that is a piece of the problem.
A second solution could be:
Put the expectedtDto in the inner-class instead of the method.
Martijn
Your code works for me. The only way I could see that expectedDto could be null within the anonymous inner class is if you're referencing it on another thread without proper synchronization.
The test-case you described works fine for me.
You should provide minimal but complete standalone test-case that illustrates the problem to get help.

Categories

Resources