public ClassContent Create(Type type) { var csharpService = new CSharpService(); var testCode = GenerateTestCode(type, csharpService); if (!testCode.Any()) { return(ClassContent.NoContent); } return(new ClassContent(testCode, csharpService.GetNameSpaces())); }
private IEnumerable <string> WriteTestMethod(Type typeUnderTest, ExceptionalCircumstance circumstance, CSharpService cSharpService) { var sanitisedExName = circumstance.ExceptionType.Split('.').Last(); var testMethodName = circumstance.OuterMethod.Name; var innerMethod = circumstance.InnerMethod; var innerDependency = circumstance.InnerMethod.DeclaringType; var ctor = typeUnderTest.GetConstructors() .FirstOrDefault(c => c.GetParameters() .Any(p => p.ParameterType == innerDependency)); if (ctor == null) { yield break; } var ctorParams = ctor.GetParameters(); var paramName = ctorParams.FirstOrDefault(p => p.ParameterType == innerDependency).Name; var dummyArgs = string.Join(",", innerMethod.GetParameters().Select(p => DummyValue(p, cSharpService))); yield return("[Test]"); yield return($"public void {testMethodName}_handles_{sanitisedExName}()"); yield return("{"); yield return($" var factory = new TestHarness();"); yield return($" factory.{StringUtils.ToUpperInitial(paramName)}"); yield return($" .Stub(x => x.{innerMethod.Name}({dummyArgs}))"); yield return($" .IgnoreArguments()"); yield return($" .Throw(new {circumstance.ExceptionType}());"); var identifier = cSharpService.GetIdentifier(typeUnderTest, VarScope.Local); yield return($" var {identifier} = factory.Create();"); yield return($" throw new NotImplementedException(\"Test placeholder not implemented.\");"); yield return("}"); }
public ClassContent Create(Type type) { var cSharpWriter = new CSharpService(); var delegationReports = ReflectionUtils.GetMethodsThatPassthrough(type); var safeCombinations = delegationReports .Where(r => r.ctor.GetParameters() .Select(p => p.ParameterType) .All(cSharpWriter.NoCircularDependenciesOrAbstract)) .ToArray(); if (!safeCombinations.Any()) { return(ClassContent.NoContent); } var linesOfCode = GenerateTestMethods(type, safeCombinations, cSharpWriter); return(new ClassContent(linesOfCode, cSharpWriter.GetNameSpaces())); }
public void Init() { _cSharpService = new CSharpService(); }
private string[] GenerateTestCode(Type type, CSharpService csharpService) { var lines = new List <string>(); var interfaceDependencies = type.GetConstructors() .SelectMany(c => c.GetParameters()) .Select(p => p.ParameterType) .Distinct() .Where(t => t.IsInterface) .Except(type.GetInterfaces()); var methodsToExceptions = new Dictionary <MethodInfo, List <string> >(); var exceptionalCircumstances = new List <ExceptionalCircumstance>(); // Get all exceptions that could be thrown by all dependent interfaces foreach (var iface in interfaceDependencies) { var sourceAssemblyVar = iface.Assembly.Location; var directory = Path.GetDirectoryName(sourceAssemblyVar); var fileRoot = Path.GetFileNameWithoutExtension(sourceAssemblyVar); var xmlDocsPath = Path.Combine(directory, fileRoot + ".xml"); var exists = File.Exists(xmlDocsPath); if (!exists) { continue; } var xmlDocument = XDocument.Load(xmlDocsPath); var allMemberElements = xmlDocument.Descendants("member").ToArray(); foreach (var ifMethod in iface.GetMethods()) { var parameters = ifMethod.GetParameters().Select(p => p.ParameterType.FullName); var paramString = string.Join(",", parameters); var docName = $"M:{iface.FullName}.{ifMethod.Name}({paramString})"; var docElement = allMemberElements.FirstOrDefault(m => m.Attribute("name")?.Value == docName); if (docElement == null) { continue; } var exceptions = docElement.Descendants("exception") .Select(e => e.Attribute("cref")?.Value) .Where(v => v != null) .Select(str => str.Substring(2)); // remove "T:" methodsToExceptions.Add(ifMethod, new List <string>(exceptions)); } } // Scan each method to see if it invokes a method than can throw foreach (var methodInfo in type.GetMethods()) { var innerCalls = ReflectionUtils.GetCalledMethods(methodInfo) .Where(m => methodsToExceptions.ContainsKey(m)); exceptionalCircumstances.AddRange( innerCalls.SelectMany(call => methodsToExceptions[call].Select( exName => new ExceptionalCircumstance(methodInfo, call, exName)))); } var tests = exceptionalCircumstances .GroupBy(c => new { c.ExceptionType, c.OuterMethod }) .Select(g => g.First()) .Select((c, i) => { var methodCode = WriteTestMethod(type, c, csharpService); return(i > 0 ? new[] { "" }.Concat(methodCode) : methodCode); }); lines.AddRange(tests.SelectMany(line => line)); return(lines.ToArray()); }
private string DummyValue(ParameterInfo arg, CSharpService cSharpService) { return(!arg.ParameterType.IsValueType || arg.ParameterType.IsArray ? "null" : cSharpService.GetInstantiation(arg.ParameterType, nonDefault: false)); }