在Java接口中模拟方法时出现Mockito问题

vzgqcmou  于 2022-11-08  发布在  Java
关注(0)|答案(1)|浏览(233)

我在使用Junit5和Mockito 3.8模拟Java接口中的一个方法时遇到了问题。测试失败,原因是:

Wanted but not invoked:
remoteCommands.getServiceStatus("ABC");
-> at com.acme.CommandHandlerTest.testServiceName(CommandHandlerTest.java:40)
Actually, there were zero interactions with this mock.

它在www.example.com的第40行失败CommandHandlerTest.java,这是

verify(remoteCommands).getServiceStatus(serviceName);

然而,当我调试代码时,我可以看到正在执行的方法,所以我知道有一个与此方法的交互,但Mockito无法识别它。
如果我遗漏了什么,请告诉我。我的代码文件如下,

命令处理程序测试.java

package com.acme;

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.rmi.RemoteException;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class  CommandHandlerTest {

    private CommandHandler commandHandler;

    @Mock
    IRemoteCommandsImpl remoteCommands;

    @BeforeEach
    void setup() {
        MockitoAnnotations.openMocks(this);
    }

    @Test
    void testDoCommand_serviceName() throws RemoteException {
        commandHandler = new CommandHandler();

        String serviceName = "ABC";
        int mockValue = 4000;

        when(remoteCommands.getServiceStatus(eq(serviceName))).thenReturn(mockValue);

        commandHandler.printServiceStatus(serviceName);

        verify(remoteCommands).getServiceStatus(serviceName);

    }
}

命令处理程序.java

package com.acme;

public class CommandHandler {

    private IRemoteCommands remoteCommands;

    public CommandHandler(){

    }

    public void printServiceStatus(String service) {

        remoteCommands = new IRemoteCommandsImpl();
        int serviceStatus = 0;

        try {
            serviceStatus = remoteCommands.getServiceStatus(service);
            System.out.println("CommandHandler->serviceStatus: "+serviceStatus);
        } catch (Exception e) {
            e.getMessage();
        }
    }
}

I远程命令.java

package com.acme;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface IRemoteCommands extends Remote
{

    public int getServiceStatus(String serviceName) throws RemoteException;

}

I远程命令实现java

package com.acme;
import java.rmi.RemoteException;

public class IRemoteCommandsImpl implements IRemoteCommands{

    @Override
    public int getServiceStatus(String serviceName) throws RemoteException {
        return 1000;
    }
}
bihw5rsg

bihw5rsg1#

CommandHandler中,创建一个新的IRemoteCommandsImpl示例,并将其分配给私有remoteCommands字段。
这意味着被模拟的remoteCommands没有被测试对象使用。
您需要重新构造代码并将remoteCommands提供给CommandHandler,最好通过构造函数:

public class CommandHandler {

    private final IRemoteCommands remoteCommands;

    public CommandHandler(IRemoteCommands remoteCommands) {
        this.remoteCommands = remoteCommands;
    }
    // ...
}

最重要的是:

  • 如果使用MockitoExtension,则不需要MockitoAnnotations.openMocks(this);

相关问题