首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PowerShell Pester Mock Rest调用

PowerShell Pester Mock Rest调用
EN

Stack Overflow用户
提问于 2021-07-25 23:27:08
回答 2查看 1.2K关注 0票数 3

对于如何在Pester中模拟Rest调用,有什么简单的方法吗?

这是我的代码,我只需要在Pester中模拟那些Rest调用并测试它们,这里有人能帮我吗?

代码语言:javascript
复制
Describe 'Test worldclockapi.com' {
    BeforeAll {
        $response = Invoke-WebRequest -Method 'GET' -Uri 'http://worldclockapi.com/api/json/utc/now'
        $responseContent = $response.Content | ConvertFrom-Json
        Write-Output $responseContent
    }

    It 'It should respond with 200' {
        $response.StatusCode | Should -Be 200
    }
    
    It 'It should have a null service response' {
        $responseContent.serviceResponse | Should -BeNullOrEmpty
    } 
    
    It 'It should be the right day of the week' {
        $dayOfWeek = (Get-Date).DayOfWeek
        $responseContent.dayOfTheWeek | Should -Be $dayOfWeek
    }
    
    It 'It should be the right year' {
        $year = Get-Date -Format 'yyyy'
        $responseContent.currentDateTime | Should -BeLike "*$year*"
    }
    
    It 'It should be the right month' {
        $month = Get-Date -Format 'MM'
        $responseContent.currentDateTime | Should -BeLike "*$month*"
    }
    
    # These two tests assume you are running this outside daylight savings (during the winter) .. hacky but good way to showcase the syntax ;)
    It 'It should not be daylight savings time' {
        $responseContent.isDayLightSavingsTime | Should -Not -Be $true
    }
    
    It 'It should not be daylight savings time another way' {
        $responseContent.isDayLightSavingsTime | Should -BeFalse
    }
}
EN

回答 2

Stack Overflow用户

发布于 2021-07-26 06:27:22

使用真正的响应作为模拟输出的模板可能是最简单的。

代码语言:javascript
复制
Invoke-WebRequest -Method 'GET' -Uri 'http://worldclockapi.com/api/json/utc/now' | 
    Export-Clixml .\response.xml

上面的命令将从API序列化为一个文件的真正响应。

现在,我们可以导入要与模拟一起使用的文件。只需使用Mock命令来定义模拟。

Mock

  • -CommandName:mocking
  • -ParameterFilter:,我们是一个可选的过滤器,它将模拟行为限制在传递给命令的参数值传递过滤器的CommandName的使用上。此value.
  • -MockWith:必须返回一个布尔ScriptBlock --指定将用于模拟CommandName的行为的ScriptBlock。缺省值为空ScriptBlock。在这里,我们导入文件作为输出。

代码语言:javascript
复制
Mock -CommandName Invoke-WebRequest -ParameterFilter { $Method -eq 'GET' } -MockWith { Import-Clixml .\response.xml }

现在,当用Invoke-WebRequest调用-Method 'Get'时,模拟将被调用,并返回我们使用Import-CliXml (或其他方法- json、xml等)导入的对象。

注意:模拟命令必须在调用我们正在模拟的命令之前出现。还请注意,即使在使用该命令的其他函数中,模拟也将被调用。

代码语言:javascript
复制
    BeforeAll {
        Mock -CommandName Invoke-WebRequest -ParameterFilter { $Method -eq 'GET' } -MockWith { Import-Clixml .\response.xml }

        # on this next line our mock will be called instead and will return our prepared object
        $response = Invoke-WebRequest -Method 'GET' -Uri 'http://worldclockapi.com/api/json/utc/now'
        $responseContent = $response.Content | ConvertFrom-Json
        Write-Output $responseContent
    }
票数 2
EN

Stack Overflow用户

发布于 2021-07-26 07:42:18

我认为Daniel's answer很棒,但是如果您正在开发一个大型或共享的存储库,那么您也需要小心地管理这些XML文件。我使用的另一个选项是,使用真正的响应为所有返回的对象提供一个大型Json文件。它可以在BeforeAllBeforeDiscovery中导入,这取决于测试的结构。

我的补充答案的原因实际上也是为了涵盖错误响应,因为有测试用例来显示如何处理REST调用失败是很重要的。在您自己的函数中包装Invoke-WebRequest可能对返回个性化错误、处理标头响应以及为站点名称或允许的一组API路径设置常量可能很有用。例如,根据PowerShell的版本,这就是我可能处理404的方式。

代码语言:javascript
复制
Context " When a path does not exist in the API" {
    BeforeAll {
        Mock Invoke-WebRequest {
            # Use the actual types returned by your function or directly from Invoke-WebRequest.
            if ($PSVersionTable.PSEdition -eq "Desktop") {
                $WR = New-MockObject -Type 'System.Net.HttpWebResponse'
                $Code = [System.Net.HttpStatusCode]::NotFound
                # Use Add-Member because StatusCode is a read-only field on HttpWebResponse
                $WR | Add-Member -MemberType NoteProperty -Name StatusCode -Value $Code -Force
                $Status = [System.Net.WebExceptionStatus]::ProtocolError
                $Ex = [System.Net.WebException]::new("404", $null, $Status, $WR)
            }
            else {
                $Message = [System.Net.Http.HttpResponseMessage]::new()
                $Message.StatusCode = [System.Net.HttpStatusCode]::NotFound
                $Ex = [Microsoft.PowerShell.Commands.HttpResponseException]::new("404", $Message)
            }
            throw $Ex
        } -ParameterFilter {
            $Uri -eq "http://worldclockapi.com/api/json/utc/NEVER" -and
            $Method -eq "Get"
        }

        $GetRestTimeParams = @{
            Uri   = "http://worldclockapi.com/api/json/utc/NEVER"
            Method = "Get"
        }
    }

    It " Get-RestTime should not run successfully" {
        { Get-RestTime @GetRestTimeParams } | Should -Throw
    }

    It " Get-RestTime should throw a 404 error" {
        $ShouldParams = @{
            # Use the actual types returned by your function or directly from Invoke-WebRequest.
            ExceptionType   = [System.Net.WebException]
            ExpectedMessage = "404: NotFound"
        }
        {
            Get-RestTime @GetRestTimeParams
        } | Should -Throw @ShouldParams
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68523189

复制
相关文章

相似问题

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