首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >很难模拟Invoke-WebRequest的BasicHtmlWebResponseObject

很难模拟Invoke-WebRequest的BasicHtmlWebResponseObject
EN

Stack Overflow用户
提问于 2020-02-13 01:01:06
回答 3查看 1.1K关注 0票数 2

我正在尝试测试PowerShell函数的这一部分:

代码语言:javascript
复制
# 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

代码语言:javascript
复制
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
}

这个断言失败是因为我没有正确地创建HttpWebResponseBasicHtmlWebResponseObject

代码语言:javascript
复制
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

代码语言:javascript
复制
Mock Invoke-WebRequest { 
    $Response = New‐MockObject -Type Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject
    $Response.Content = '<?xml version="1.0" encoding="...'
}

但是,Content属性是只读的。

** /edit **

我遗漏了什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-02-13 11:51:55

一种稍微简单一点的替代方法可能是将您的invoke-webrequest包装在一个函数中,然后对其进行模拟。例如。

代码语言:javascript
复制
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更容易创建。

代码语言:javascript
复制
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模拟返回一个哈希表,该哈希表具有所需的属性:

代码语言:javascript
复制
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)

票数 1
EN

Stack Overflow用户

发布于 2020-02-13 02:11:36

在PowerShell内核上,这对我不起作用:

代码语言:javascript
复制
[System.Net.HttpWebResponse].GetField('m_StatusCode', 'NonPublic, Instance')

这就是为什么你的Mock没有返回你期望的结果。然而,这一行在Windows PowerShell上是有效的。不确定PSCore上正确的等价物是什么,需要研究,但我想我会在此期间带你走到这一步。

票数 1
EN

Stack Overflow用户

发布于 2020-02-13 03:14:10

这是可行的:

代码语言:javascript
复制
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
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60193524

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档