Configuration‎ > ‎

Creating QBO3 C# Unit Test Classes

posted Jul 1, 2015, 10:51 AM by Eric Patrick   [ updated Jan 5, 2017, 5:43 AM ]

Creating a Unit Test

Application tier unit tests should be created to handle architect-level unit tests that are inappropriate or impractical for a power user to run via Jasmine.

Configuring app tier unit tests to establish a working QBO environment requires some extra configuration steps:
  • A working QBO3 website must be on the same machine that will be running unit tests: c:\inetpub\wwwroot
  • Pre and post-build events are used to copy the configuration files and DLLs from the working website to the test project's output directory
To create application-tier unit tests:
  • From Visual Studio, choose New Project > Visual C# > Tests > Unit Test Project:
    • Ensure that you have selected Templates > Visual C# > Unit Test Project
    • Ensure that the Name field adheres to the following pattern: qbo.*.Tests, where * is the Solution that you are testing. This is critical.
    • Ensure that the Solution field is set to: Add to solution
  • Create pre-build and post-build events
    • Open the Project properties (right-click on the Project and select Properties)
    • Navigate to Build Events
    • Populate the Build Events menu as shown, with the code snippets below
      • Pre-build:
md $(TargetDir)\Config
copy c:\inetpub\wwwroot\Config\*.* $(TargetDir)\Config
robocopy c:\inetpub\wwwroot\bin\ $(TargetDir) 
if %errorlevel% leq 3 exit 0 else exit %errorlevel%
      • Post-build:
copy c:\inetpub\wwwroot\web.config $(TargetDir)\$(ProjectName).dll.config

By convention, QBO3 unit tests should be created in Source > Trunk > qbo.3 > qbo.Core > Tests.  See the qbo.Core.Tests.sln in that folder for examples.

Note: originally, the pre- and post-build scripts leverages a .csproj variable called BaseWebSite. The intent of this was to allow different developers to locate their 'local configuration' wherever they wanted, and have the test project use that without deviating from source control. However, simply changing the .csproj file deviates from source control, so this never actually helped. Instead, make sure you have a 'good' install in c:\inetpub\wwwroot.

Testing Sugar

The qbo.Test.Helpers project contains a bunch of classes and extension methods that simplify your life as a developer.

BaseTest

This class does a few things to help you.
  • IPerson User: this is a QBO user that can be used when creating QBO3 classes. It defaults to admin@quandis.com, but you can override this value in your c:\inetpub\wwwroot\web.config if you wish.
  • string GetRandomString(): generates a short random string, typically use when naming new DB records (e.g. a DecisionTemplate, or a Contact)
  • Setup() / TearDown(): methods that create a new TransactionScope that database calls run under. By default, you can create DB records in your tests, and when the test completes, any DB changes will be rolled back, so you don't have to 'clean up'. This can be bypassed if necessary.
Override

Part of qbo.Test.Helpers.Extensions, this method overrides an application setting (in test memory only).

using qbo.Test.Helpers.Extensions;
...
qbo.Message.Properties.Settings.Default.Override("DefaultFromAddress", Settings.Default.FromAddress, "dude@quandis.com");

MockQueue

This can be used to inspect what's happening with the QBO3 Queuing infrastructure. It is an in-memory queue, capable of pushing, popping, and executing items in a queue.

var item = new SmartWorklistMember(User) { ... };
// Wire a mock queue, and set Priority = 1 to trigger each queued message to also execute
SmartWorklistMemberObject.QueueConfig.Queues.Add(new Queue() Type = typeof(MockQueue), Name = "MockQueue", Priority = 1 });
// Call queue, and tell QBO3 to use our just-created MockQueue
item.Queue("AutoAssign", "MockQueue", "...".ToProperties());
// MockQueue.Items contains all the queued items, easily inspected for various properties
Assert.IsTrue(MockQueue.Items.ContainsKey("SmartWorklistMember/AutoAssign"));

MockStatement

Part of qbo.Test.Helpers.ObjectConfigurationExtensions, this adds a statement "on the fly" to a QBO3 class, and wires it in memory (to handle inheritance, etc.).

var bindBySSN = contact.Configuration.MockStatement(new DbStatement()
{
Name = "AutoBindBySSN_Spec",
Query = "SELECT ContactID FROM Contact WHERE USSSN = @USSSN",
Parameters = new DbParameterCollection() 
{
new DbParameter() { Name = "USSSN", DbType = DbType.String },
new DbParameter() { Name = "SpecRequired", DbType = DbType.String }
}
});

MockService

Part of qbo.Test.Helpers.ObjectConfigurationExtensions, this adds an IService "on the fly" to a QBO3 class.

public class DummyService: AbstractService 
{
...
public override IServiceResult Invoke(IDictionary<string, object> parameters)
{
// do something easily tested from your test code here
}
}
...
PersonObject person = new PersonObject(User).Select<PersonObject>(User.UserID);
person.Configuration.MockService<DummyService>("OperationToBindToDummyService");

See Also

Comments