Correct TestDrive usage

I’m trying to test a script which stores some files on hard disk. During the test I would like to store a file to TestDrive:\ and check if it was indeed created. The problem is that file always gets created in “$env:TEMP\myfile.txt”. Could you please explain what am I missing here?

Function Get-FilePath {
    return "$env:TEMP\myfile.txt"
"Some Content" | Out-File (Get-FilePath)
Describe "Script" {
    Function Get-FilePath {}
    Mock Get-FilePath { return "TestDrive:\myFile.txt" }
    . "$PSScriptRoot\Script.ps1"
    It "File should be created in TestDrive" {
        Test-Path (Get-FilePath) | Should Be $true
    It "File should not be created in $env:Temp" {
        Test-Path "$env:TEMP\myfile.txt" | Should Be $false
    if (Test-Path "$env:TEMP\myfile.txt") {
        Remove-Item "$env:TEMP\myfile.txt"

You do not need to define Get-FilePath again in your test. The mock will take care of that. When you do that, your mock is applying to that function and not the one defined in your script.ps1 file.

Hi Adam,
Thanks for reply. If I’m not defining it, I get CommandNotFoundException and if I move script dot-source up, then it creates file in $env:temp and in It block it looks for file in TestDrive.

Ah. I see. This is where code refactoring comes into play. It seems like you’re just testing if Get-FilePath returns what you expect it to since you don’t have the actual file creation step inside of that function. If this is the case, I suggest remove the Out-File functionality from the script altogether and building a simple test to ensure that Get-FilePath returns the expected string like this:

describe 'Get-FilePath' {
   $result = . $PSSscriptRoot\script.ps1

   it 'returns the temp file path' {
       $result | should be 'C:\Windows\Temp\myfile.txt'

If you do need to confirm a function creates a file in a specific location you could also use a mock assertion to ensure Add-Content in this case used the expected path.


function New-File {
    Add-Content -Path "$env:TEMP\myfile.txt" -Value ''

Then the test would look like this:

describe 'New-File' {
    mock 'Add-Content'
    . $PSScriptRoot\script.ps1

    it 'should create the file in the expected location' {
        Assert-MockCalled -CommandName 'Add-Content' -Times 1 -ParameterFilter { $Path -eq 'C:\Users\Adam\AppData\Local\Temp\myfile.txt' }

Heh, that makes sense. Ended up with this

$settingsContent = @"
#Spark Settings
#Mon May 09 11:36:00 EEST 2016

Function Get-SparkPropertiesFile {
    Write-Output (Join-Path $env:USERPROFILE "AppData\Roaming\Spark\")

Function New-PropertiesFile {
    if (!(Test-Path (Split-Path (Get-SparkPropertiesFile))))
        mkdir (Split-Path (Get-SparkPropertiesFile))
        try {
            Add-Content -Value $settingsContent -Path (Get-SparkPropertiesFile) -Encoding UTF8 -ErrorAction Stop
        catch {
            Write-Log -Message "Failed to create new properties file" -Level error -Path $env:gpLogfile
if (($env:gpObject -eq 'User') -and ($env:gpState -eq 'Logon')) {
$projectRoot = (get-item $PSScriptRoot).parent.parent.parent.FullName
$ScriptsDir = "$projectRoot\GPScripts\Scripts"
$scriptName = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '.Tests.ps1', ''

Describe "User_Set-Spark" {
    $env:gpObject = 'User'
    $env:gpState = 'Logon'

    Mock 'Add-Content'
    . "$ScriptsDir\$scriptName\$scriptName.ps1"
    It "Should create new properties file" {
        Assert-MockCalled -CommandName 'Add-Content' -Times 1 -ParameterFilter { $Path -eq "$env:USERPROFILE\AppData\Roaming\Spark\" }

Thank you. Looking forward to your pester talk today. Cheers!

For some reason my previous message was treated as spam. Just wanted to say thank you for help. Everything working smooth now.