" java.util.NoSuchElementException:java.util.Optional.get"中没有值。在使用模拟的Spock测试中

时间:2017-09-07 10:46:23

标签: unit-testing mocking spock

我试图为以下方法编写一个常规的单元测试:

/* eslint-env mocha */

该方法调用以下内容:

public Set<ObjectName> getAll()
{

    return getMBeanServerConnection().map(mbsc ->
    {
        try
        {
            return mbsc.queryNames(null, null);
        }
        catch (IOException e)
        {
            logger.log(Level.SEVERE, "An exception was thrown: ", e);
            return Collections.<ObjectName>emptySet();
        }
    }).get();
}

然后:

    private Optional<MBeanServerConnection> getMBeanServerConnection()
{
    return virtualMachineHelper.getMb();
}

这只是一个将调用转发给mbsc.queryNames(null,null)的方法

我试图在调用getAll()时测试,然后调用mbsc.queryNames(null,null)一次。

我有以下代码:

public Optional<MBeanServerConnection> getMb()
{
    VirtualMachine virtualMachine = getOmsVirtualMachine();
    if (virtualMachine == null)
    {
        return Optional.empty();
    }
    try
    {
        Properties props = virtualMachine.getAgentProperties();
        String connectorAddress =
            props.getProperty(JMX_REMOTE_PROPERTY);

        JMXServiceURL url = new JMXServiceURL(connectorAddress);
        JMXConnector connector = JMXConnectorFactory.connect(url);
        MBeanServerConnection mbsc = connector.getMBeanServerConnection();
        return Optional.of(mbsc);
    }
    catch (IOException e)
    {
        logger.log(Level.SEVERE, "An exception was thrown: ", e);
        return Optional.empty();
    }
}

但这会产生以下错误:

  

java.util.NoSuchElementException:没有值

def virtualMachineHelperMock = Mock(VirtualMachineHelper)
def mBeanServerConnection = Mock(MBeanServerConnection)

ObjectNamesRepository objectNamesRepository = new ObjectNamesRepository(virtualMachineHelperMock)

void setup() {
    virtualMachineHelperMock.getMb() >> Optional.of(mBeanServerConnection)
}

def "when calling getAll then queryNames is called from mBeanServerConnection"() {
    when:
    objectNamesRepository.getAll()

    then:
    1 * mBeanServerConnection.queryNames(null, null)
}

1 个答案:

答案 0 :(得分:2)

这是因为没有记录mbsc.queryNames(null, null)来电的存根响应,因此模拟returns the default valuenullcontract of Optional.map()如下:

  

如果存在值,请将提供的映射函数应用于该值,然后   如果结果为非null ,则返回描述结果的Optional。   否则返回空的可选。

您从Optional调用中获得空map(),因此例外。

要解决此问题,您可以按照Spock documentation中的说明在同一个互动中存根通话:

1 * mBeanServerConnection.queryNames(null, null) >> Collections.emptySet()