我正在尝试测试PowerShell函数的这一部分:
# post
$Response = Invoke-WebRequest -Method POST -Uri $Uri -Body $Body -ContentType 'application/xml'
# parse Response.Content; return as System.Xml.XmlDocument
[xml]$Response.Content通过模拟Invoke-WebRequest返回的BasicHtmlWebResponseObject
Mock Invoke-WebRequest {
$WebResponse = [System.Net.HttpWebResponse]::new()
[System.Net.HttpWebResponse].GetField('m_StatusCode', 'NonPublic, Instance').SetValue(
$WebResponse,
200,
'NonPublic,SetField',
$null,
(Get-Culture)
)
$Content = '<?xml version="1.0" encoding="UTF-8"?><response><control>failure<status></status></control><operation><result><status>failure</status></result></operation></response>'
$Response = [Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject]::new($WebResponse,$Content)
return $Response
}这个断言失败是因为我没有正确地创建HttpWebResponse或BasicHtmlWebResponseObject:
It "returns the response's Content object" {
# act
$Content = Send-Request -Session $Session
# assert
Assert-MockCalled Invoke-WebRequest
$Content | Should -BeOfType [xml]
$Content.response.control.status | Should -Be 'success'
$Content.response.operation.result.status | Should -Be 'success'
}**编辑**
我考虑过使用New-MockObject
Mock Invoke-WebRequest {
$Response = New‐MockObject -Type Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject
$Response.Content = '<?xml version="1.0" encoding="...'
}但是,Content属性是只读的。
** /edit **
我遗漏了什么?
发布于 2020-02-13 11:51:55
一种稍微简单一点的替代方法可能是将您的invoke-webrequest包装在一个函数中,然后对其进行模拟。例如。
function Get-XmlFromUri
{
param( $Uri, $Method, $Body )
$Response = Invoke-WebRequest -Method $Method -Uri $Uri -Body $Body -ContentType 'application/xml’
[xml]$Response.Content
}现在,您可以模拟Get-XmlFromUri,只从硬编码的xml返回一个System.Xml.XmlDocument对象,这比需要反射调用spin up的BasicHtmlWebResponseObject更容易创建。
Mock Get-XmlFromUri {
[xml] '<?xml version="1.0" encoding="UTF-8"?>
<response>
<control><status>success</status></control>
<operation><result><status>success</status></result></operation>
</response>'
}或者,根据您的代码需要它在多大程度上类似于BasicHtmlWebResponseObject,您可以从invoke-webrequest模拟返回一个哈希表,该哈希表具有所需的属性:
Mock Invoke-WebRequest {
new-object pscustomobject -property @{
Content = '<?xml version="1.0" encoding="UTF-8"?>
<response>
<control><status>success</status></control>
<operation><result><status>success</status></result></operation>
</response>’
}
}(为代码格式道歉-目前在凌晨4点在iPhone上输入一只手,抱着一个不太困的婴儿:-S)
发布于 2020-02-13 02:11:36
在PowerShell内核上,这对我不起作用:
[System.Net.HttpWebResponse].GetField('m_StatusCode', 'NonPublic, Instance')这就是为什么你的Mock没有返回你期望的结果。然而,这一行在Windows PowerShell上是有效的。不确定PSCore上正确的等价物是什么,需要研究,但我想我会在此期间带你走到这一步。
发布于 2020-02-13 03:14:10
这是可行的:
Mock Invoke-WebRequest {
$Response = New-MockObject -Type Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject
$Content = `
'<?xml version="1.0" encoding="UTF-8"?>
<response>
<control><status>success</status></control>
<operation><result><status>success</status></result></operation>
</response>'
$Response | Add-Member -NotePropertyName Content -NotePropertyValue $Content -Force
$Response
}https://stackoverflow.com/questions/60193524
复制相似问题