英文:
Unit testing a Powershell Azure Function App?
问题
I have an Azure Function written in Powershell:
function Invoke {
param($Request)
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = "Hello!"
})
}
I have a Pester unit test for this function:
Describe "Invoke" {
It "Returns a 200 response" {
$Response = Invoke -Request [HttpRequestContext]@{}
$Response.StatusCode | Should Be ([HttpStatusCode]::OK)
}
}
Running this test yields:
Describing Invoke
[-] Returns a 200 response 4ms (3ms|1ms)
RuntimeException: Unable to find type [HttpRequestContext].
Presumably the PowerShellWorker injects these types when it runs the script and so they are not available when Pester invokes the test. In falling order of desirability, how can I:
- Import these types in my test run? For example, is there a module I could import?
- Inject mocks of these types? Pester has support for creating mocks of objects, but not inject types?
- Ask the PowerShellWorker to invoke the function from my test? (I could probably invoke
func host start
and write integration tests instead, but I would really prefer to have unit tests if possible.)
I'd appreciate any lead that can help me with this.
UPDATE: As pointed out in comments, I had deleted a param()
when compacting my example. To clarify, the idea is to support type annotations in both test and production code.
UPDATE2: Corrected spelling as per mclayton's suggestion.
英文:
I have an Azure Function written in Powershell:
function Invoke {
param($Request)
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = "Hello!"
})
}
I have a Pester unit test for this function:
Describe "Invoke" {
It "Returns a 200 response" {
$Response = Invoke -Request [HttpRequestContext]@{}
$Response.StatusCode | Should Be ([HttpStatusCode]::OK)
}
}
Running this test yields:
Describing Invoke
[-] Returns a 200 response 4ms (3ms|1ms)
RuntimeException: Unable to find type [HttpRequestContext].
Presumably the PowerShellWorker injects these types when it runs the script and so they are not available when Pester invokes the test. In falling order of desirability, how can I:
- Import these types in my test run? For example, is there a module I could import?
- Inject mocks of these types? Pester has support for creating mocks of objects, but not inject types?
- Ask the PowerShellWorker to invoke the function from my test? (I could probably invoke
func host start
and write integration tests instead, but I would really prefer to have unit tests if possible.)
I'd appreciate any lead that can help me with this.
UPDATE: As pointed out in comments, I had deleted a param()
when compacting my example. To clarify, the idea is to support type annotations in both test and production code.
UPDATE2: Corrected spelling as per mclayton's suggestion.
答案1
得分: 1
我尚未看到一种真正简洁的方法来进行 PowerShell Azure Functions 的单元测试...或者至少它们确实没有像 C#/Javascript/Python 一样受到普遍的关注。
然而,你可以在 Pester 中使用 New-MockObject 来模拟类型。
我还看到一些使用 entryPoints 来运行脚本,然后独立测试脚本而不必依赖于 Azure Function 的工作时环境的方法,但你想要深入探讨多深入呢?
英文:
I've not seen a really concise approach to unit testing PowerShell Azure Functions....or at least they certainly get less love than C#/Javascript/Python in general.
You can however mock the type in pester using New-MockObject
I've also seen ways of using entryPoints to run a script and then test the script independently of your Azure Function so you don't have to rely on the worker runtime at all but how deep down the rabbit hole do you want to go?!
答案2
得分: 0
我今天遇到了这个问题,通过将run.ps1
中的using
语句移到profile.ps1
文件的顶部,并在BeforeEach
中的单元测试中添加一个模拟类型,然后再点源run.ps1
来解决它:
enum HttpStatusCode {
OK
InternalServerError
}
class HttpResponseContext {
[HttpStatusCode]$StatusCode
[string]$ContentType
[string]$Body
}
function Push-OutputBinding($Name, $Value) {}
对我来说起到了奇效。
英文:
I just ran into this today, and I solved it by moving the using
statement in run.ps1
to the top of the profile.ps1
file, and adding a mock type to the unit tests in the BeforeEach
, before dot-sourcing run.ps1
:
enum HttpStatusCode {
OK
InternalServerError
}
class HttpResponseContext {
[HttpStatusCode]$StatusCode
[string]$ContentType
[string]$Body
}
function Push-OutputBinding($Name, $Value) {}
Worked like a charm for me.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论