PowerMock ExpectNew creating real objects instead of mocked Ones

114 Views Asked by At
public  class PersistenceManager {

    public boolean addUser(User user) {
        UserPersistor userPersistor = new UserPersistor(user) {

            @Override
            void somemethod() {
                // TODO Auto-generated method stub
                
            }
            
        };
        userPersistor.addUser();
        System.out.println("PersistenceManager added user ");
        return true;
    }
    
    
    class User {
        
        public String firstName;
        public String lastName;
        
        
        public User(String firstName, String lastName) {
            super();
            this.firstName = firstName;
            this.lastName = lastName;
        }       
    }
    
    abstract class UserPersistor {
        
        public UserPersistor( ) {
            
        }
        public UserPersistor(User user) {
            
        }
        public void addUser() {
            System.err.println("UserPersistor added user ");
        }
        abstract void somemethod();
    }
}   

import static org.powermock.api.easymock.PowerMock.createMock;
import static org.powermock.api.easymock.PowerMock.expectNew;
import static org.powermock.api.easymock.PowerMock.expectLastCall;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest( PersistenceManager.class )
public class PersistenceManagerTest {
    
    private User user = null;
    
    @Before
    public void before() throws Exception {
        
        user = createMock(User.class);      
        UserPersistor userPersistor = createMock(UserPersistor.class);
        userPersistor.addUser();
        expectLastCall();
        
        expectNew(UserPersistor.class, user).andReturn(userPersistor);      

        PowerMock.replayAll();
    }
    @Test
    public void testaddUser() {

        PersistenceManager tested = new PersistenceManager();
        tested.addUser(user);
        PowerMock.verifyAll();
    }
}

Whats wrong with above code? I dont see mocked object for UserPersistor. Meaning, i dont want to see "UserPersistor added user " printed. It should not do anything. But it is printing it since real object of UserPersistor is created. I am facing this problem in my actual project, thought would simulate and try to solve in a much smaller context. But I am stumped.

1

There are 1 best solutions below

0
On

That's because you are not expecting to instantiate UserPersistor but an anonymous inner class extending UserPersistor.

To do that you need to retrieve that class, mock it and expect it. PowerMock has a Whitebox class to do that. You are exposing the class implementation when using it. I would recommend that you refactor your code to inject the code instead. But if you really want to, you should write this:

@Before
public void before() throws Exception {
    user = createMock(PersistenceManager.User.class);

    Class<Object> clazz = Whitebox.getAnonymousInnerClassType(PersistenceManager.class, 1);
    PersistenceManager.UserPersistor userPersistor = createMock(clazz);
    userPersistor.addUser();

    expectNew(clazz, user).andReturn(userPersistor);

    PowerMock.replayAll();
}