Last active
March 8, 2022 21:03
-
-
Save JerryNixon/0bb42e8dfc53165938fd11199f5f4a43 to your computer and use it in GitHub Desktop.
Write your own unit test framework
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Collections.Generic; | |
using JerryUnit; | |
using static JerryUnit.UnitTestAttribute; | |
public class Program | |
{ | |
public static void Main() | |
{ | |
TestRunner.Run(new Custom.MyLibraryTests()); | |
Console.WriteLine($"{Environment.NewLine}End"); | |
} | |
} | |
namespace Custom | |
{ | |
public static class MyLibrary | |
{ | |
public static string Reverse(string text) | |
{ | |
if (text is null) | |
throw new ArgumentNullException(nameof(text)); | |
var array = text.ToCharArray(); | |
Array.Reverse(array); | |
return new String(array); | |
} | |
} | |
public class MyLibraryTests | |
{ | |
[UnitTest] | |
public void Reverse_String_Reversed() => | |
Reverse("Jerry", "yrreJ"); | |
[UnitTest] | |
public void Reverse_Empty_Empty() => | |
Reverse(string.Empty, string.Empty); | |
[UnitTest] | |
public void Reverse_Null_ArgumentNullException() | |
{ | |
try { MyLibrary.Reverse(null); } | |
catch (ArgumentNullException) { return; } | |
Assert(false, "Expected ArgumentNullException"); | |
} | |
private static void Reverse(string original, string expected) | |
{ | |
var actual = MyLibrary.Reverse(original); | |
Assert(expected == actual, $"Expected '{expected}' == '{actual}'"); | |
} | |
} | |
} | |
namespace JerryUnit | |
{ | |
public class UnitTestAttribute : Attribute | |
{ | |
public static void Assert(bool result, string message = null) | |
{ | |
if (!result) throw new Exception(message); | |
} | |
} | |
public static class TestRunner | |
{ | |
public static void Run(object list) | |
{ | |
if (list is null) | |
throw new ArgumentNullException(nameof(list)); | |
var tests = FindTests(list); | |
if (!tests.Any()) | |
throw new System.ArgumentException("Test list is empty."); | |
RunTests(list, tests).ToList().ForEach(x => Console.WriteLine(((x.Success) | |
? $"✅ Pass: {(list)}.{x.Name}" | |
: $"❌ Fail: {(list)}.{x.Name} > Error: {x.Message}"))); | |
static IEnumerable<System.Reflection.MethodInfo> FindTests(object list) => | |
list.GetType().GetMethods().Where(x => x.GetCustomAttributes(typeof(UnitTestAttribute), false).Any()); | |
static IEnumerable<(bool Success, string Name, string Message)> RunTests(object list, IEnumerable<System.Reflection.MethodInfo> tests) | |
{ | |
foreach (var test in tests) | |
{ | |
var message = string.Empty; | |
try { test.Invoke(list, null); } | |
catch (Exception e) { message = (e.InnerException is not null) ? e.InnerException.Message : e.Message; } | |
yield return (string.IsNullOrEmpty(message), test.Name, message); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://dotnetfiddle.net/ZYVV1K