lazywinadmin / AdsiPS

PowerShell module to interact with Active Directory using ADSI and the System.DirectoryServices namespace (.NET Framework)
http://www.lazywinadmin.com
MIT License
193 stars 46 forks source link

Add Pester tests for each cmdlet #56

Open Stephanevg opened 5 years ago

Stephanevg commented 5 years ago

I have noticed that this module lives without pester tests. This makes refactoring pretty difficult.

I would like to start with this issue, the process add pester tests to this module, which we could track here.

lazywinadmin commented 5 years ago

Thanks @Stephanevg ! We do have some basic unit tests here: https://github.com/lazywinadmin/AdsiPS/tree/master/Tests

Feel free to improve them

omiossec commented 5 years ago

Hi It can be difficult. AdsiPS functions are more or less wrappers to .net Methods and objects. You can mock this object. You can mock this Method and this Objects, but for few functions it doesn't make sense since .net call cover all the function.

omiossec commented 5 years ago

I think that we have 2 solutions Try to mock .net class by creating a fake class (it's because I can't mock a class with method and constructors)

refactor all the command with wrapper functions, they will handle all the .net logic so we can focus on PowerShell Code

lazywinadmin commented 5 years ago

I asked the question on the #testing channel on Slack @chrisdent:

for unit testing ADSI, I tend to write quite extensive mocked objects. Got an example somewhere... https://floobits.com/PoshCode/PowerShell.Slack.com/file/chrisdent/ADAuthorizedDhcpServer.tests.ps1:235 the DSC resource this one tests is beside it in floobits. I have a few others that are pure ADSI, they all use the same approach to handle unit testing. the extra functions these call, such as NewDirectorySearcher are very simple wrappers to give me hooks to mock calls. e.g.

    [OutputType([System.DirectoryServices.DirectorySearcher])]
    param ( )

    [ADSISearcher]::new()
}

ofc this is only unit testing, code paths, command calls, but I still find it valuable. It does not entirely replace testing against something living, but as you've found that's really hard to get in CI (be it AzDO, or AppVeyor, or anywhere else). it's also worth noting the existence of New-MockObject which will give you a completely disarmed instance of an object. You would have to rewire any properties or methods you expect to call.