抑制超类方法在PowerMockito中不起作用

时间:2017-01-20 07:20:07

标签: java junit4 powermockito

我想通过Users方法取消insertUserPowerMockito.suppress方法。但似乎抑制方法效果不佳。即它无论如何都是呼叫方法。
我尝试使用PowerMockito.doNothing().when(Users.class, "insertUser", users);代替,但我得到了NullPointerException。

java.lang.NullPointerException
    at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.addAnswersForStubbing(PowerMockitoStubberImpl.java:67)
    at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:42)
    at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:105)
    at test.UsersImplTest.insertUser(UsersImplTest.java:39)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)

我知道调用super.insertUser(users);并不是一个好主意,我知道调用它并不是一个好设计。但我想知道为什么suppress方法不起作用。您可以在下面看到代码。

User.class

package test;

public class User {

    private int id;
    private String name;

    public User() {
    }

    public User(String name) {
        this.name = name;
    }

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

超级

package test;

import java.sql.Connection;
import java.util.List;

public abstract class Users {

    private Connection connection;

    public Users(Connection connection) {
        this.connection = connection;
    }

    public abstract int getId();
    public abstract User getUser();
    public abstract String getName();
    public abstract void setName(String name);

    public Connection getConnection() {
        return connection;
    }

    public void insertUser(List<User> users) {
        throw new UnsupportedOperationException();
    }
}

扩展超类

package test;

import java.sql.Connection;
import java.util.List;

public class UsersImpl extends Users {

    public UsersImpl(Connection connection) {
        super(connection);
    }

    @Override
    public int getId() {
        return 0;
    }

    @Override
    public User getUser() {
        return null;
    }

    @Override
    public String getName() {
        return null;
    }

    @Override
    public void setName(String name) {
    }

    private void validate(List<User> users) {
        for (User user : users) {
            if (isExists(user)) {
                users.remove(user);
            }
        }
    }

    private boolean isExists(User user) {
        return false;
    }

    public void insertUser(List<User> users) {
        validate(users);
        super.insertUser(users);
    }
}

这里我在插入之前验证数据。即检查用户是否已存在。之后我将用户插入数据库。这是我跑的测试:

package test;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.api.support.membermodification.MemberMatcher;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

@RunWith(PowerMockRunner.class)
@PrepareForTest({UsersImpl.class, Users.class})
public class UsersImplTest {

    private Connection connection;
    private UsersImpl usersImpl;
    private List<User> users;

    @Before
    public void setUp() throws Exception {

        connection = PowerMockito.mock(Connection.class);
        PowerMockito.suppress(MemberMatcher.constructor(UsersImpl.class));
        usersImpl = PowerMockito.spy(new UsersImpl(connection));
        users = new ArrayList<>();
        users.add(new User("John"));
        users.add(new User("Smith"));
        users.add(new User("Caro"));
        users.add(new User("Debby"));
    }

    @Test
    public void insertUser() throws Exception {

        PowerMockito.suppress(MemberMatcher.method(Users.class, "insertUser", List.class));
        PowerMockito.doReturn(true).when(usersImpl, "isExists", new User("Smith"));

        usersImpl.insertUser(users);
    }
}

1 个答案:

答案 0 :(得分:0)

在您提到的评论中,您使用的是powermock版本1.6.4依赖项。我用1.6.4和1.6.5测试了代码,并且在使用1.6.5时它只强制使用insertUser()方法:

<dependency> 
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>1.6.5</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito</artifactId>
    <version>1.6.5</version>
    <scope>test</scope>
</dependency>

我发现版本1.6.3的相关错误问题:

https://github.com/powermock/powermock/issues/590

当试图压制间谍的方法时会发生错误。