简体   繁体   English

在.ps1脚本中模拟功能

[英]Mock a function within a .ps1 script

I have a PowerShell .ps1 file which contains functions at the top of the script followed by different commands calling these functions. 我有一个PowerShell .ps1文件,该文件的脚本顶部包含函数,然后是调用这些函数的不同命令。 I am using Pester to unit test my script file. 我正在使用Pester对脚本文件进行单元测试。

How do I mock a function that is within my PowerShell .ps1 script? 如何模拟PowerShell .ps1脚本中的函数?

I have tried mocking the function, but I get an error saying "could not find command". 我尝试模拟该函数,但收到一条错误消息“找不到命令”。

I have also tried adding an empty "dummy" function in the describe block. 我也尝试过在describe块中添加一个空的“虚拟”函数。 This doesn't give me the above error, but it is not mocking the function within the script correctly. 这不会给我上面的错误,但是它没有正确地模拟脚本中的函数。

I have two files. 我有两个文件。 One to hold the tests and another that holds the functions and calls to the functions. 一个用于保存测试,另一个用于保存函数并调用函数。 Below are two examples: 以下是两个示例:

File1.ps1 File1.ps1

Function Backup-Directory([switch]$IsError)
{
    If($IsError)
    {
        Write-Error "Error"
        Exit 1
    }
}

Backup-Directory $true

File2.Tests.ps1 File2.Tests.ps1

$here = (Split-Path -Parent $MyInvocation.MyCommand.Path) -replace '\\test', '\main'
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
$productionFile = "$here\$sut"

Describe "File1" {

    Context "When the Back-Directory outputs an error." {

        # Arrange
        Mock Back-Directory { }
        Mock Write-Error

        # Act
        & $productionFile
        $hasSucceeded = $?

        # Assert
        It "Calls Backup-Directory" {
            Assert-MockCalled Backup-Directory -Exactly 1 -ParameterFilter {
                $IsError -eq $true
            }
        }

        It "Writes error message." {
            Assert-MockCalled Write-Error -Exactly 1 -ParameterFilter {
                 $Message -eq "Error"
            }
        }

        It "Exits with an error." {
            $hasSucceeded | Should be $false
        }
    }
}

I don't think this is possible. 我认为这是不可能的。 At least with your current implementation. 至少在您当前的实现中。 I asked this same question a while back... Pester Issue 414 不久前,我问了同样的问题... Pester Issue 414

BUT you could split out that inner function into another script file in the same directory allowing you to unit test and mock it. 但是您可以将该内部函数拆分为同一目录中的另一个脚本文件,从而可以进行单元测试和模拟。 You would just have to dot source the function in your main script file to be able to use it: 您只需要在主脚本文件中加点源函数即可使用它:

Main-Function.ps1: 主Function.ps1:

# Main script
function Main-Function {
    # if debugging, set moduleRoot to current directory
    if ($MyInvocation.MyCommand.Path) {
        $moduleRoot = Split-Path -Path $MyInvocation.MyCommand.Path
    }else {
        $moduleRoot = $PWD.Path
    }

    # dot source the inner function
    . "$moduleRoot\Inner-Function.ps1"

    Write-Output "This is the main script. Calling the inner function"

    Inner-Function

    Write-Output "Back in the main script"
}

Inner-Function.ps1: 内Function.ps1:

function Inner-Function {
    Write-Output "This is the inner function"
}

Main-Function.Tests.ps1: 主Function.Tests.ps1:

$moduleRoot =  Split-Path -Parent $MyInvocation.MyCommand.Path 

# Load Testing Function
. "$moduleRoot\Main-Function.ps1"

# Load Supporting Functions
. "$moduleRoot\Inner-Function.ps1"

Describe 'Main Script' {
    Mock Inner-Function { return "This is a mocked function" }

    It 'uses the mocked function' {
        (Main-Function -match "This is a mocked function") | Should Be $true
    }
}

This is a really nice approach because we can unit test the inner function and as the logic grows, adding tests to it is very easy (and can be done in isolation from the rest of the scripts/functions). 这是一个非常好的方法,因为我们可以对内部函数进行单元测试,并且随着逻辑的增长,向其添加测试非常容易(并且可以与其余脚本/函数隔离地进行)。

Inner-Functions.Tests.ps1: 内Functions.Tests.ps1:

$moduleRoot =  Split-Path -Parent $MyInvocation.MyCommand.Path 

# Load Testing Function
. "$moduleRoot\Inner-Function.ps1"

Describe 'Inner Function' {
    It 'outputs some text' {
        Inner-Function | Should Be "This is the inner function"
    }
}

There are two main points here... 这里有两个要点...

Finding the dependent function location regardless of your current execution directory... 无论您当前的执行目录如何,都可以找到依赖函数的位置...

if ($MyInvocation.MyCommand.Path) {
        $moduleRoot = Split-Path -Path $MyInvocation.MyCommand.Path
    }else {
        $moduleRoot = $PWD.Path
    }

AND

Dot Sourcing depending functions in the main function as well as the unit test files... . "$moduleRoot\\Inner-Function.ps1" 点取决于采购的主要功能以及单元测试文件的功能... . "$moduleRoot\\Inner-Function.ps1" . "$moduleRoot\\Inner-Function.ps1"

Split-Path -Path $MyInvocation.MyCommand.Path is $null in a user session, but will NOT be $null when invoked from within an execution context. Split-Path -Path $MyInvocation.MyCommand.Path在用户会话中为$null ,但在执行上下文中调用时不会为$null Meaning, you could be in C:\\users\\nhudacin and still load this script/module correctly. 这意味着,您可能位于C:\\users\\nhudacin ,但仍正确加载了此脚本/模块。 Otherwise you would have to always execute this script/module from within the same directory as where it's located without using $MyInvoation variable. 否则,您将必须始终从与其所在目录相同的目录中执行此脚本/模块,而不使用$MyInvoation变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python如何在另一个函数中模拟一个函数 - Python how to mock a function within another function 如何在 Function 中模拟 function。 是否可以使用两个或多个补丁来模拟 Function 中的 function 调用? - How to mock a function within a Function. Is it possible to use two or more Patches to mock a function call within a Function? 用于脚本加载的模拟实用程序函数 - Mock utility function that is being used on script load 笑话单元测试 - 异步 function 中异步 function 的模拟值 - Jest unit test - mock value of async function within async function 如何将开玩笑的模拟函数分配给 React 组件中的函数? - How to assign a jest mock function to a function within a React component? 模拟 function 没有在异步 function 中被调用 - Mock function isn't getting called within an async function Spock 如何在方法中模拟 Autowired 类的 function 调用 - Spock How to mock Autowired class' function call within a method 如何模拟从不同模块导入的方法中导入的函数 - How to mock a function, that is imported within an imported method from different module 如何在类中的方法中模拟外部函数 - How can I mock an external function within a method in a class 如何模拟出__init__文件中未公开的功能? - How to mock out a function that is not exposed from within __init__ file?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM