Defined Variable not resolved when Pester test executes

This topic contains 5 replies, has 3 voices, and was last updated by  Michael 4 weeks, 1 day ago.

  • Author
    Posts
  • #99334

    Michael
    Participant

    Hi everyone,

    I am testing my self-made PS module and when the PS module gets imported, there is a script that gets dot-sourced to setup the environment prior to loading the module. There is a variable that gets defined during the environment set up and gets utilized in one of my functions within the module.

    Now with that explained, when I run my Pester test, I can see that the variable is null due to my verbose logging even though my verbose logging shows that the script is dot-sourced and loaded prior to executing the test.

    Now if I set the variable to a Global variable, then my test works because the variable is now defined. I do not want to setup my variable to a Global scope if it is not necessary.

    Any suggestions on what I need to do to prevent from changing my variable to a Global defined variable or best practice?

    Thanks,
    Michael

  • #99360

    Adam Bertram
    Moderator

    Could you provide some code examples and how you've got your Pester test set up?

  • #99369

    Michael
    Participant

    Hi Adam,

    First I must say that I am fan of your work and I also purchased your Pester book on leanpub. It was a great read and I try to adopt many of the things I learned from there. However, I am still a beginner with it comes to Pester testing. Thank you for that great book.

    Now, back to business. I didn't provide you with my actual code, due to the fear of accidentally adding something here that shouldn't be on the web. But the below snippets should show you what I am running into.

    # this is within my module manifest
    # Script files (.ps1) that are run in the caller's environment prior to importing this module.
    ScriptsToProcess = '.\SetupEnvironment.ps1'
    
    # within setupEnvironment.ps1 I have a few things happening, but depending on certain dependancies
    # the variable value could be blah or foo, but the variable is always defined otherwise an error throws 
    # and the module doesn't get imported. 
    ...
    $message = "foo"
    ...
    
    # function within my module
    function Get-Message {
    # the variable that is defined in my setupenvironment.ps1 script  
    if($message)
      {
        $obj = [pscustomObject] @{
               Message = $message
              }
        return $obj
      }
    }
    
    # within my Pester test
    # I have also tried to dot-source the setupEnvironment.ps1 file here to but that didn't seem to help me out any
    Import-Module MyModule -Force
    
    InModuleScope MyModule {
        Describe "Get-Message" {
          it 'should return a object' {
            $result = Get-Message
    
            $result.Message | Should be "foo" 
            # however this is going to fail, because no object gets returned because $message is $null
          }
        }
    }
    

    I hope this is a good enough example. Let me know if you have any further questions.

    Thanks,
    Michael

  • #99393

    Brian Bunke
    Participant

    Hello! Would/could you consider defining $message a different way?

    First, remove the SetupEnvironment.ps1, or at least comment out the line of the variable. Then,

    # PSD1 file
    
    # Script module or binary module file associated with this manifest.
    RootModule = 'MyModule.psm1'
    
    # PSM1 file
    
    $script:message = 'foo'
    

    This works for your function and your test, and is a pretty common "module scope" practice. (Available to the module but obscured from the end user, the same way a private function behaves.)

  • #99438

    Adam Bertram
    Moderator

    I would honestly leave it in the global scope. It's not going to force you to re-architect your process and it's not necessarily "bad" to do. If you're concerned with leaving the global variable hanging around, you could put $MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { Remove-Variable -Name message -Scope Global } in your module to ensure it gets removed when your module is unloaded.

    Otherwise, I agree with Brian.

  • #99514

    Michael
    Participant

    Thanks Gents!

You must be logged in to reply to this topic.