# Tahir Hassan's Blog

My Technical Notes

## Saturday, 25 March 2017

### Generating Random Strings in PowerShell

As part of unit testing my PowerShell functions, I have noticed a small potential issue with having data hard-coded into unit tests. Such tests can be made to pass by hard-coding the answer in the tested function. For instance we could have a unit test for a function called Concat-String that takes two string arguments and concatenates them together:


$result = Concat-String "Tahir" "Riyadh" Assert-AreEqual "TahirRiyadh"$result


Such a test could easily be passed by hard-coding a return value:


Function Concat-String([string]$First, [string]$Second) {
}


(Of course, a unit-testing purist would say that you need multiple tests to prevent the possibility of hard-coded values, but that is besides the point - I only want to write one unit test, not many versions of the same test with different data).

Instead, what I am now using to generate test data is the following function, New-RandomString:



Function New-RandomString {
param([Parameter()][int]$Size=10)$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_".ToCharArray();

$bytes = & {$data = [byte[]]::new($Size)$crypto = [System.Security.Cryptography.RNGCryptoServiceProvider]::new();
$crypto.GetBytes($data)
$data }$str = [char[]]($bytes | % {$_ % $chars.Length } | % {$chars[$_] }) [string]::new($str)
}


Instead of hard-coding test data in the unit test, New-RandomString can be used to give appropriate test values:


$firstVal = New-RandomString 15$secondVal = New-RandomString 20
$result = Concat-String$firstVal $secondVal$expected = $firstVal +$secondVal
Assert-AreEqual $expected$result


Such a test cannot be passed by hard-coding a correct return value. It can also be run multiple times to ensure that it passes i all cases.