Test Accessors and Test Constructors
While working with the normal code we often see that a method is used x-times. Unfortunately the counter counts all calls including test-calls, so the number can be very misleading. It's even possible that a method is never used in production, but is called 1000 times in tests.
To avoid this problem, tests should prefer to use Test Accessors and Test Constructors where applicable to ensure clarity and reduce the access count. As a rule of thumb, if a method is used more than 3 times in tests, it should be considered for a Test Accessor, because then the counter cannot easily be used to determine if the method is still in use.
The way this should be implemented is as follows:
- In some cases, a simple method on the test class like
GetThing(...)
orThingTac(...)
is enough, especially if this method is only used in this test class. - In most cases, create static extension methods ending with
Tac
- soIThing.Get(...)
becomes a staticGetTac(this IThing parent, ...)
method.- These can be in the test project where it is used
- ... or in a TestHelper project if it's used in multiple test projects
Examples follow.
Simple Test Constructor in the Class
This shows a method on the class (for use there only) to create a specific class. It will help to keep the access-count on the constructor low.
/// Empty Test Constructor
/// </summary>
private static CacheItemPolicyMaker EmptyTco() => new() { Log = new Log("Tst.CacSpx") };
Static Class with Test Accessor
This is a static class with a test accessor method, inside the test-project where it is used.
using System.Runtime.Caching;
namespace ToSic.Eav.Caching;
internal static class TestAccessors
{
internal static CacheItemPolicy CreateResultTac(this IPolicyMaker policyMaker)
=> policyMaker.CreateResult();
}
Static Class with Test Accessor in a TestHelper Project
using System.Collections.Immutable;
namespace ToSic.Eav.Data.Build;
public static class ValueBuilderTestAccessors
{
/// <summary>
/// Test accessor to reduce use-count of the real code
/// </summary>
/// <returns></returns>
public static IValue BuildTac(this ValueBuilder vBuilder, ValueTypes type, object value, IList<ILanguage> languages)
=> vBuilder.Build(type, value, languages?.ToImmutableList());
public static IValue BuildTac(this ValueBuilder vBuilder, ValueTypes type, object value, IImmutableList<ILanguage> languages)
=> vBuilder.Build(type, value, languages);
}