Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Private Functions #247

Closed
iainbrighton opened this Issue Dec 23, 2014 · 7 comments

Comments

Projects
None yet
2 participants
@iainbrighton
Copy link

iainbrighton commented Dec 23, 2014

Is there anyway to test private/nested functions?

I have a module that is comprised of multiple .ps1 files exporting public functions. There appears no way to test the 'internal' functions without exposing them. The -InModuleScope won't work as the functions are hidden within the module itself!

I appreciate that normally you would only test the external surface area. However - in this instance - I need to also test the internal logic. Looks like I'll need to dynamically parse the ps1 files and load the internal functions before testing them, maybe via the AST? If so, I'll try and put something together to enable testing of named internal functions?

Thanks, Iain

@dlwyatt

This comment has been minimized.

Copy link
Member

dlwyatt commented Dec 23, 2014

That's exactly what the InModuleScope command is for. If you can give more specifics on what you're trying to test where that command isn't working, I can either help you change the tests to get them working, or figure out how to improve Pester's capabilities, if needed.

@dlwyatt

This comment has been minimized.

Copy link
Member

dlwyatt commented Dec 23, 2014

BTW, the bottom example at https://github.com/pester/Pester/wiki/Unit-Testing-within-Modules covers this scenario.

@iainbrighton

This comment has been minimized.

Copy link
Author

iainbrighton commented Dec 24, 2014

Thanks Dave. Essentially I'm trying to test the "InnerPrivate" function below.

function OuterExported {
    param ()

    ## Trying to test this nested/private function
    function InnerPrivate {
        param ()
        Write-Output 'InnerPrivate'
    }

    Write-Output (InnerPrivate)

}

## Can test this with -InModuleScope
## or by testing the .ps1 file
function OuterPrivate {
    param ()
    Write-Output 'OuterPrivate'
}

Export-ModuleMember -Function OuterExported

I have a whole load of internal logic that isn't exposed that I need to test. It's actually a boat-load of .ps1 (and associated .tests.ps1 files) that are dot-sourced in a .psm1 file. I can already test the OuterPrivate function without -InModuleScope, but can't seem to get at the private/nested function.

Does this make sense? I think we'll need to load the private function in Pester's scope to be able to test it. It's hidden by design but we can walk the .ps1 file (via the AST) and load it for testing?

Cheers, Iain

@dlwyatt

This comment has been minimized.

Copy link
Member

dlwyatt commented Dec 24, 2014

Oh, I see. There's really no reason to define a function inside another function when you're using a script module. When you do that, the "inner" nested function can't be mocked by Pester. You could technically mock the commands that InnerPrivate called, but you'd have to invoke OuterExported to trigger them.

I don't think there's anything we can or should do with Pester to support that scenario. Just move the nested functions out into the main scope of the script module, and only export the things that you want to expose to the user.

@iainbrighton

This comment has been minimized.

Copy link
Author

iainbrighton commented Dec 24, 2014

Agreed - there's no reason to do this for modules. However, I'd also like to release this module as a 'bundled' .ps1 file that could be dot-sourced or placed at the beginning of an existing script. In this scenario private functions in the module scope will be exposed.

I'd like to keep these hidden to avoid a lot of unnecessary clutter. Some government agencies won't permit 3rd party modules ;)

I'm sure I can get the private functions loaded into Pester's scope for testing. I'll do some testing..

@dlwyatt

This comment has been minimized.

Copy link
Member

dlwyatt commented Dec 24, 2014

You can probably use the AST (assuming you're testing on PowerShell 3.0 or later; doing this in 2.0 could be a pain) to identify the code in those functions and load them into your session in the test script. However, there's a chance that the functions might not work as you expect them to, depending on whether they are written to access any of the variables in the parent function's scope.

Either way, I don't think this is functionality that should be included in the Pester module itself.

@iainbrighton

This comment has been minimized.

Copy link
Author

iainbrighton commented Dec 24, 2014

No problem. I'm targeting v3 as the module uses ordered hashtables already. Coming from a C# background, I never count on the parent scopes' variables - lexical scoping all the way! I'll put something together and blog it, just in case anyone else ever needs this fringe use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.