Saturday, January 17, 2015

Creating your own unit testing framework for PowerShell - Part 2

Before we dig into the testing process, one of the main activities to be done as part of the Arrange phase is to populate or ModuleObject properties with the CommandInfo object that is used at the Acting phase of our test framework. For iterating through all the properties and reading the attributes using reflection and setting the values of the ModuleObject implementation, we’ll make use of the Visitor pattern.
Our PsModuleVisitor implementation looks like

internal class PsModuleElement
{
    internal static void Accept(TPsModule module) where TPsModule : class, new()
    {
        var visitor = new PsModuleVisitor();
        visitor.Visit(module);
    }
}     

internal class PsModuleVisitor : IVisitor where TPsModule : class, new()
{
    public void Visit(TPsModule module)
    {
        PopulateModuleInfo(module);
    }

    private void PopulateModuleInfo(TPsModule module)
    {
        var methodProperties = typeof(TPsModule).GetProperties()
            .Where(prop => prop.IsDefined(typeof(PsModuleFunctionAttribute), false)).ToList();

        foreach (var methodProperty in methodProperties)
        {
            var modAttribute = methodProperty.GetCustomAttribute<PsModuleFunctionAttribute>();
            var name = modAttribute.Name;
            var paramAttributes = methodProperty.GetCustomAttributes<PsModuleParameterAttribute>().ToList();
            IDictionary parameters = null;
            if (paramAttributes.Any())
            {
                parameters = new Dictionary<string, string>();
                foreach (var paramAttribute in paramAttributes)
                {
                    parameters.Add(paramAttribute.Key, paramAttribute.Value);
                }
            }
            var commandInfo = new PsCommandInfo { Name = name, Parameters = parameters };
            methodProperty.SetValue(module, commandInfo);
        }
    }
}

internal interface IVisitor<in T> where T: class,new()
{
    void Visit(T module);
}


Next we’ll create our PowerShellHost test instance to invoke the methods from a visited ModuleObject 

No comments: