-
Notifications
You must be signed in to change notification settings - Fork 0
CommandTesting
Anrijs Vitolins edited this page May 19, 2021
·
4 revisions
- Create new XUnit test project in visual studio.
- Add reference to
Salix.Dapper.Cqrs.MsSql.Testing.XUnit
package. - Add reference to project, containing
ICommand
implementations. - Make sure special function exists in SQL Server database
There are many functionalities, like base classes and interfaces provided in Salix.Dapper.Cqrs.MsSql.Testing.*
package, which are to be applied/used for assembly testing purpose.
As we need actual database with structure matching application needs - tests are considered "assembly" or "integration" tests due to requirement of external IO component (database).
See Assembly testing page on how to set things up.
All above then gets together in actual test class.
using System;
using Salix.Dapper.Cqrs.Abstractions;
using Salix.Dapper.Cqrs.MsSql.Testing.XUnit;
using MyApp.Commands;
using Xunit;
using Xunit.Abstractions;
namespace Sample.AspNet5Api.Database.Tests
{
/// <summary>
/// Test validates all existing ICommand implementations against database.
/// </summary>
public class CommandStatementValidationTests : DatabaseTestsBase
{
/// <summary>
/// Constructor.
/// </summary>
public CommandStatementValidationTests(ITestOutputHelper outputHelper, SqlDatabaseFixture testFixture) =>
this.InitializeTestContext(outputHelper, testFixture);
/// <summary>
/// MEGA-TEST, which looks up all ICommand implementations (see <see cref="HelperQueryCommandClasses.CommandValidatorClassesForAssemblyType"/> method in helper)
/// It validates SqlStatement inside ICommand class by calling its Validate method.
/// </summary>
/// <param name="commandClassType">Type of the command class (supplied by [MemberData] attribute method).</param>
/// <remarks>
/// [MemberData] attribute parameters are:
/// 1 - method to get all types of ICommandValidator classes,
/// 2 - any existing ICommandValidator class from assembly where all those classes are located,
/// 3 - Class (static), where Method (1) is to be found.
/// </remarks>
[Theory(DisplayName = "Command validate for: ")]
[MemberData(nameof(HelperQueryCommandClasses.CommandValidatorClassesForAssemblyType), typeof(ArtistCreateCommand), MemberType = typeof(HelperQueryCommandClasses))]
public void CommandClass_SqlValidate_Succeeds(Type commandClassType)
{
// We need as-if-real parameters supplied for query (if any)
object[] parameters = HelperQueryCommandClasses.CreateDummyParametersForType(commandClassType, TestObjectFactory.Instance);
var instance = (ICommandValidator)Activator.CreateInstance(commandClassType, parameters);
instance.Validate(this.TestFixture.SqlSession);
// Make sure UPDATE and DELETE statements are containing WHERE clause to avoid all-update or all-delete situations.
if ((instance.SqlStatement.StartsWith(
"UPDATE",
StringComparison.InvariantCultureIgnoreCase)
|| instance.SqlStatement.StartsWith("DELETE", StringComparison.InvariantCultureIgnoreCase))
&& !instance.SqlStatement.Contains("WHERE", StringComparison.InvariantCultureIgnoreCase))
{
throw new DatabaseStatementSyntaxException("UPDATE or DELETE statement without WHERE clause.", instance.SqlStatement);
}
}
}
}
If all is done as shown above (see also Sample solution for actual code), then executing this one single test will find all existing ICommandValidator
implementation classes and runs a test on them.
See also: