Skip to content
Daryl LaBar edited this page Jan 29, 2025 · 4 revisions

Welcome to the XrmUnitTest wiki!

Initial Setup

Either check out the Example project (https://github.com/daryllabar/XrmUnitTest) or utilize the Visual Studio Solution Accelerator in the XrmToolBox to quickly setup XrmUnitTest in your own project.

Videos

Test Frameworks

XrmUnitTest will work with any testing framework (MsTest, XUnit, NUnit, etc) but will need to have a Test Provider class defined and registered. Here are example classes for MSTest, XUnit, and NUnit. They will need to be defined using the TestSettings.TestFrameworkProvider.Configure.

MsTest

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
#if NET
using DataverseUnitTest;
#else
using DLaB.Xrm.Test;
#endif
class MsTestProvider : ITestFrameworkProvider
{
    public Type TestMethodAttributeType => typeof (TestMethodAttribute);

    public Exception GetFailedException(string message)
    {
        return new AssertFailedException(message);
    }

    public Exception GetInconclusiveException(string message)
    {
        return new AssertInconclusiveException(message);
    }
}

XUnit

using System;
using Xunit;
using Xunit.Sdk;
#if NET
using DataverseUnitTest;
#else
using DLaB.Xrm.Test;
#endif

namespace XrmUnitTest.Test
{
    class XUnitTestProvider : ITestFrameworkProvider
    {
        public Type TestMethodAttributeType => typeof(FactAttribute);

        public Exception GetFailedException(string message)
        {
            return new XunitException(message);
        }

        public Exception GetInconclusiveException(string message)
        {
            //Xunit does not provide an inconclusive, so no message will be thrown
            return new XunitException(message);
        }
    }
}

NUnit

using System;
using System.Collections.Generic;
using NUnit.Framework;
#if NET
using DataverseUnitTest;
#else
using DLaB.Xrm.Test;
#endif

class NUnitTestProvider : IMultiTestMethodAttributeTestFrameworkProvider
{
    public Type TestMethodAttributeType => null;

    private static readonly HashSet<Type> TestAttributeTypes = [..new[] { typeof(TestAttribute), typeof(TestCaseAttribute) }];

    public HashSet<Type> TestMethodAttributeTypes => TestAttributeTypes;

    public Exception GetFailedException(string message)
    {
        return new AssertionException(message);
    }

    public Exception GetInconclusiveException(string message)
    {
        return new InconclusiveException(message);
    }
}

How to Use

  • Entity Builders - Entity Builders fluent builders that are used to help make Unit Tests DRY and easier to read, by easing the amount of code required to instantiate data. Check out the LeadBuilder in XrmUnitTest.Test.Builder namespace for an example of how to use one, and the DLaB.Xrm.LocalCrm.Tests.LocalCrmDatabaseOrganizationServiceExecuteTests for how it is used:
var lead = new LeadBuilder
{
    Lead = new Lead
    {
        Address1_Line2 = "Test Address1_Line2",
        Address1_Line3 = "Test Address1_Line3",
        Description = "Test Description",
        Fax = "555-555-1234",
        JobTitle = "Sales Agent",
        LeadSourceCodeEnum = Lead_LeadSourceCode.Advertisement,
        PreferredContactMethodCodeEnum = Lead_PreferredContactMethodCode.Phone,
        WebSiteUrl = "https://github.com/daryllabar/XrmUnitTest",
        TransactionCurrencyId = currency.ToEntityReference()
    }
}
    .WithAddress1()
    .WithAddress2()
    .WithDoNotContact(false)
    .WithEmail()
    .WithName()
    .WithPhone()
    .Build();

You can see that the lead has some custom attributes that are being set, as well add Address1, Address2, the do not contact fields, Email, Name, and Phone. The test doesn't care what the actual values are, just that they are populated, so this removes the need to have duplicate initialization values throughout your project, as well as makes it extremely readable as to what data you need. Other methods could be added such as .WithFranceAddress() for example, if you need an address that isn't in the United States.

How to Extend

Coming Soon