Skip to content

Instantly share code, notes, and snippets.

@JerryNixon
Last active March 8, 2022 21:03
Show Gist options
  • Save JerryNixon/0bb42e8dfc53165938fd11199f5f4a43 to your computer and use it in GitHub Desktop.
Save JerryNixon/0bb42e8dfc53165938fd11199f5f4a43 to your computer and use it in GitHub Desktop.
Write your own unit test framework
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);
}
}
}
}
}
@JerryNixon
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment