Search code examples
powershellpester

Can I mock a DllImport-ed function?


Suppose I have a powershell script that adds a custom type, such as in:

Add-Type -TypeDefinition @'

   public struct LogEntry {
       //...
   }

    public static class Native
    {
        [DllImport("some.dll", EntryPoint = "GetLogs")]
        public static extern UInt32 GetLogs([Out] LogEntry[] results);
     }
'@

Can I mock this GetLogs() so I can return test data instead of calling my native DLL?

InModuleScope "mod.psd1"  {
    Describe "Process logs" {
        Context "Function Exists" {
        //failed: Mock [Native]::GetLogs { return 5 } -Verifiable 
        //failed: Mock [Native] -member GetLogs { return 5 } -Verifiable 

        It "Should work" {
           [Native]::GetLogs | should be 5
         }
        }
    }
}

I get a variation of this error (first syntax complaining about [Native]::GetLogs and second one about [Native].

[-] Error occurred in Context block 3.13s
[13352]       CommandNotFoundException: Could not find Command [Native]
[13352]       at Validate-Command, C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0\Functions\Mock.ps1: line 801
[13352]       at Mock, C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0\Functions\Mock.ps1: line 168

Is it the problem that is not finding the mock target in my module, because it's added dynamically? Or am I just doing it wrong (which is most likely case)?


Solution

  • Assuming you're on 5.1, you could create a mock class:

    class Native {
        static [int] GetLogs() {
            return 5
        }
    }
    

    Which you could then invoke:

    [Native]::GetLogs()
    # => 5
    

    As an aside, mocking interop will be difficult no matter what you do really.