"java.util.NoSuchElementException: No value present at java.util.Optional.get" 在使用模拟的 Spock 测试中
"java.util.NoSuchElementException: No value present at java.util.Optional.get" in a Spock test using mocks
我正在尝试为以下方法编写 groovy 单元测试:
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();
}
然后:
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();
}
}
这只是一种将调用转发给 mbsc.queryNames(null, null)
的方法
我正在尝试测试调用 getAll() 时 mbsc.queryNames(null, null) 被调用一次。
我有以下代码:
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)
}
但这会产生以下错误:
java.util.NoSuchElementException: No value present
at java.util.Optional.get(Optional.java:135)
at com.ullink.ulconsole.repository.ObjectNamesRepository.getAll(ObjectNamesRepository.java:73)
at com.ullink.ulconsole.repository.ObjectNamesRepositorySpec.GetAll(ObjectNamesRepositorySpec.groovy:32)
这是因为没有记录 mbsc.queryNames(null, null)
调用的存根响应,所以 mock returns the default value: null
. And the contract of Optional.map()
如下:
If a value is present, apply the provided mapping function to it, and
if the result is non-null, return an Optional describing the result.
Otherwise return an empty Optional.
您从 map()
调用中得到一个空的 Optional
,因此异常。
要解决此问题,您可以在同一交互中存根调用,如 Spock documentation:
中所述
1 * mBeanServerConnection.queryNames(null, null) >> Collections.emptySet()
我正在尝试为以下方法编写 groovy 单元测试:
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();
}
然后:
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();
}
}
这只是一种将调用转发给 mbsc.queryNames(null, null)
的方法我正在尝试测试调用 getAll() 时 mbsc.queryNames(null, null) 被调用一次。
我有以下代码:
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)
}
但这会产生以下错误:
java.util.NoSuchElementException: No value present
at java.util.Optional.get(Optional.java:135)
at com.ullink.ulconsole.repository.ObjectNamesRepository.getAll(ObjectNamesRepository.java:73)
at com.ullink.ulconsole.repository.ObjectNamesRepositorySpec.GetAll(ObjectNamesRepositorySpec.groovy:32)
这是因为没有记录 mbsc.queryNames(null, null)
调用的存根响应,所以 mock returns the default value: null
. And the contract of Optional.map()
如下:
If a value is present, apply the provided mapping function to it, and if the result is non-null, return an Optional describing the result. Otherwise return an empty Optional.
您从 map()
调用中得到一个空的 Optional
,因此异常。
要解决此问题,您可以在同一交互中存根调用,如 Spock documentation:
中所述1 * mBeanServerConnection.queryNames(null, null) >> Collections.emptySet()