How to create a Custom Workflow Activity Integration Test

In this example, we explain how to test the custom workflow activity TotalOpportunities, which calculates the total value of an account based on its related opportunities. So, our test is going to verify this value is the right one given an account and two related opportunities.

To create this test, just follow the next steps:
  • Create the new test action "Test Total Opportunities Activity". This action will only be an instrument to call the custom workflow activity and pass the corresponding parameters.
  • Right click on the folder WFActivities of the Integration Test project
  • Add the new Class "TestTotalOpportunitiesActivity.cs"
  • Make this class inherit from the base class XrmIntegrationTest and implements its corresponding methods

TotalOpportunities.cs activity code:
public class TotalOpportunities : BaseCodeActivity
    {
        #region Input Parameters

        [Input("Account")]
        [ReferenceTarget("account")]
        public InArgument<EntityReference> AccountReference { get; set; }

        #endregion

        #region Output Parameters

        [Output("Total")]
        public OutArgument<Money> Total { get; set; }

        #endregion

        /// <summary>
        /// Executes the workflow activity.
        /// </summary>
        /// <param name="executionContext">The execution context.</param>
        protected override void ExecuteActivity(CodeActivityContext executionContext)
        {
            Guid accountId = AccountReference.Get(executionContext).Id;
            decimal total = 0;

            using (XrmServiceContext myContext = new XrmServiceContext(this.OrganizationService))
            {
                var opps = from opp in myContext.OpportunitySet
                            where opp.AccountId.Id == accountId
                            select opp.ActualValue;

                foreach (Money actual in opps)
                {
                    total += actual.Value; 
                }
            }

            Total.Set(executionContext, new Money(total));
        }
    }

"Test Total Opportunities Activity" CRM action:
xRMTestFramework_CreateTestTotalOpportunitiesActivityAction.jpg

TestTotalOpportunitiesActivity.cs activity test code:
[TestClass]
    public class TestTotalOpportunitiesActivity : XrmIntegrationTest
    {
        #region Instance Variables

        private Account account;
        private List<Opportunity> accountOpportunities;

        #endregion

        #region Setup

        protected override OrganizationRequest SetupTriggerRequest()
        {
            CrmHelpers.SetConfigurationSetting(this.OrganizationService,"AutoNumberPrefix","Test"+DateTime.Now);

            account = new Account();
            account.Name = "TestTotalOpportunitiesActivity " + DateTime.Now;
            account.Id = this.OrganizationService.Create(account);

            Opportunity opportunity1 = new Opportunity();
            opportunity1.Name = "TestTotalOpportunitiesActivity 1 " + DateTime.Now;
            opportunity1.ActualValue = new Money(1000);
            opportunity1.ParentAccountId = account.ToEntityReference();
            Opportunity opportunity2 = new Opportunity();
            opportunity2.Name = "TestTotalOpportunitiesActivity 2 " + DateTime.Now;
            opportunity2.ActualValue = new Money(3000);
            opportunity2.ParentAccountId = account.ToEntityReference();

            opportunity1.Id = this.OrganizationService.Create(opportunity1);
            opportunity2.Id = this.OrganizationService.Create(opportunity2);

            accountOpportunities = new List<Opportunity>(2);
            accountOpportunities.Add(opportunity1);
            accountOpportunities.Add(opportunity2);

            OrganizationRequest executeActionRequest = new OrganizationRequest("xdft_TestTotalOpportunitiesActivity");
            executeActionRequest["Target"] = account.ToEntityReference();
            return executeActionRequest;
        }

        #endregion

        #region Test

        [TestMethod]
        public void RunTestTotalOpportunities()
        {
            base.Test();
        }

        #endregion

        #region Verify

        protected override void Verify()
        {
            Assert.IsNull(Error);

            Assert.IsTrue(this.TriggerResponse.Results.Contains("AccountValue"));
            
            decimal expectedTotal = this.accountOpportunities.Sum(op => op.ActualValue.Value);

            decimal actualTotal = ((Money)this.TriggerResponse["AccountValue"]).Value;

            Assert.AreEqual(expectedTotal, actualTotal);
        }

        #endregion

        #region Clean up

        protected override void CleanUp()
        {
            base.CleanUp();

            foreach (Opportunity opp in accountOpportunities)
                this.OrganizationService.Delete(opp.LogicalName, opp.Id);

            this.OrganizationService.Delete(account.LogicalName, account.Id);

        }

        #endregion
    }

As you can see, the test is clearly composed by four sections:
  • Setup: Create and initialised the required test records. SetupTriggerRequest carries out the next actions:
    • Prepare the configuration setting AutoNumberPrefix
    • Create an account and two related opportunities
    • Return the organisation request to be executed during the next Test phase, which is the action we have created earlier "{xdft_TestTotalOpportunitiesActivity}"
  • Test: Execute the message "{xdft_TestTotalOpportunitiesActivity}"
  • Verify: It is the heart of the test where the assertions are evaluated. In this case, we verify that the sum of the opportunity values for the given account is the expected one.
You should specially notice the assertion Assert.IsNull(Error), which is offered out of the box with the xRM Test Framework to verify base failures or exceptions (e.g. Service not available or authentication error)
  • Clean Up: It tidies up again the environment after the Setup and Test phases. For instance, in this test we need to delete the created Opportunities and the Account record.

Last edited Jun 9, 2014 at 6:27 PM by rtebar, version 3

Comments

No comments yet.