Remove Jenkinsfile and add unit tests for various models including Address, Domain, Nameserver, Section, Session, Subnetwork, Tag, Vlan, and Vrf. Introduce mock classes for HTTP requests and cmdlet testing.
This commit is contained in:
139
classlib.tests/Mocks/CmdletTestHelper.cs
Normal file
139
classlib.tests/Mocks/CmdletTestHelper.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
namespace PS.IPAM.Tests.Mocks;
|
||||
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Host;
|
||||
using System.Reflection;
|
||||
|
||||
/// <summary>
|
||||
/// Helper class for testing PowerShell cmdlets.
|
||||
/// </summary>
|
||||
public class CmdletTestHelper<T> : IDisposable where T : PSCmdlet, new()
|
||||
{
|
||||
private readonly T _cmdlet;
|
||||
private readonly List<object> _output = new();
|
||||
private readonly List<ErrorRecord> _errors = new();
|
||||
private bool _disposed;
|
||||
|
||||
public CmdletTestHelper()
|
||||
{
|
||||
_cmdlet = new T();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cmdlet instance for setting parameters.
|
||||
/// </summary>
|
||||
public T Cmdlet => _cmdlet;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the output objects written by the cmdlet.
|
||||
/// </summary>
|
||||
public IReadOnlyList<object> Output => _output.AsReadOnly();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the errors written by the cmdlet.
|
||||
/// </summary>
|
||||
public IReadOnlyList<ErrorRecord> Errors => _errors.AsReadOnly();
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether any errors were written.
|
||||
/// </summary>
|
||||
public bool HasErrors => _errors.Count > 0;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the cmdlet and captures output.
|
||||
/// </summary>
|
||||
public void Invoke()
|
||||
{
|
||||
// Use reflection to call the protected ProcessRecord method
|
||||
var processMethod = typeof(T).GetMethod("ProcessRecord",
|
||||
BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
if (processMethod == null)
|
||||
{
|
||||
throw new InvalidOperationException("ProcessRecord method not found on cmdlet.");
|
||||
}
|
||||
|
||||
// Set up a mock command runtime to capture output
|
||||
var runtime = new MockCommandRuntime(_output, _errors);
|
||||
var runtimeProperty = typeof(Cmdlet).GetProperty("CommandRuntime",
|
||||
BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
runtimeProperty?.SetValue(_cmdlet, runtime);
|
||||
|
||||
// Invoke the method
|
||||
try
|
||||
{
|
||||
processMethod.Invoke(_cmdlet, null);
|
||||
}
|
||||
catch (TargetInvocationException ex) when (ex.InnerException != null)
|
||||
{
|
||||
// Unwrap the exception
|
||||
throw ex.InnerException;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mock implementation of ICommandRuntime for capturing cmdlet output.
|
||||
/// This is a minimal implementation that only handles the methods we need for testing.
|
||||
/// </summary>
|
||||
internal class MockCommandRuntime : ICommandRuntime
|
||||
{
|
||||
private readonly List<object> _output;
|
||||
private readonly List<ErrorRecord> _errors;
|
||||
|
||||
public MockCommandRuntime(List<object> output, List<ErrorRecord> errors)
|
||||
{
|
||||
_output = output;
|
||||
_errors = errors;
|
||||
}
|
||||
|
||||
public PSHost Host => null!;
|
||||
public PSTransactionContext CurrentPSTransaction => null!;
|
||||
|
||||
public bool ShouldContinue(string query, string caption) => true;
|
||||
public bool ShouldContinue(string query, string caption, ref bool yesToAll, ref bool noToAll) => true;
|
||||
public bool ShouldProcess(string target) => true;
|
||||
public bool ShouldProcess(string target, string action) => true;
|
||||
public bool ShouldProcess(string verboseDescription, string verboseWarning, string caption) => true;
|
||||
public bool ShouldProcess(string verboseDescription, string verboseWarning, string caption, out ShouldProcessReason shouldProcessReason)
|
||||
{
|
||||
shouldProcessReason = ShouldProcessReason.None;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TransactionAvailable() => false;
|
||||
|
||||
public void ThrowTerminatingError(ErrorRecord errorRecord) => throw errorRecord.Exception;
|
||||
|
||||
public void WriteCommandDetail(string text) { }
|
||||
public void WriteDebug(string text) { }
|
||||
public void WriteError(ErrorRecord errorRecord) => _errors.Add(errorRecord);
|
||||
public void WriteObject(object sendToPipeline) => _output.Add(sendToPipeline);
|
||||
public void WriteObject(object sendToPipeline, bool enumerateCollection)
|
||||
{
|
||||
if (enumerateCollection && sendToPipeline is System.Collections.IEnumerable enumerable)
|
||||
{
|
||||
foreach (var item in enumerable)
|
||||
{
|
||||
_output.Add(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_output.Add(sendToPipeline);
|
||||
}
|
||||
}
|
||||
public void WriteProgress(ProgressRecord progressRecord) { }
|
||||
public void WriteProgress(long sourceId, ProgressRecord progressRecord) { }
|
||||
public void WriteVerbose(string text) { }
|
||||
public void WriteWarning(string text) { }
|
||||
}
|
||||
Reference in New Issue
Block a user