jordimontana82 / fake-xrm-easy

The testing framework for Dynamics CRM and Dynamics 365 which runs on an In-Memory context and deals with mocks or fakes for you
https://dynamicsvalue.com/get-started/overview?source=git
Other
262 stars 182 forks source link

Need help creating 1:N associations #525

Closed dewilliams704 closed 4 years ago

dewilliams704 commented 4 years ago

I'm trying to write a Unit test for a custom action plugin. I need to associate 2 custom entities to an incident, but my understanding of how to do so is not working. Here is a code snippet of my unit test:

`XrmFakedContext fakedOrgSvcContext = new XrmFakedContext();

IOrganizationService fakedOrgSvc = fakedOrgSvcContext.GetOrganizationService();

Entity sourceCase = new Entity("incident") { Id = Guid.NewGuid() }; Console.WriteLine("sourceCase GUID: " + sourceCase.Id.ToString()); sourceCase["lvocsc_casetype"] = new OptionSetValue(512200002);

XrmFakedPluginExecutionContext fakedPluginContext = new XrmFakedPluginExecutionContext { MessageName = "lvocsc_CopyCaseAction", Stage = 40, InputParameters = new ParameterCollection { ["caseId"] = sourceCase.Id.ToString(), ["copyAction"] = "clone"} };

Entity failingSample = new Entity("lvocsc_failingsamplerequest") { Id = Guid.NewGuid() }; failingSample["statuscode"] = new OptionSetValue(1); failingSample["lvocsc_regardingcase"] = sourceCase.ToEntityReference(); failingSample["lvocsc_name"] = "Test Sample";

Entity onwardSampleShipment = new Entity("lvocsc_onwardsampleshipment") { Id = Guid.NewGuid() }; onwardSampleShipment["statuscode"] = new OptionSetValue(1); onwardSampleShipment["lvocsc_regardingcase"] = sourceCase.ToEntityReference(); onwardSampleShipment["lvocsc_name"] = "Test Shipment";

string caseFailingSampleRelationshipName = "lvocsc_failingsamplerequest_incident_regardingcase"; XrmFakedRelationship caseFailingSampleRelationship = new XrmFakedRelationship("incidentid", "lvocsc_regardingcase", "incident", "lvocsc_failingsamplerequest");

string caseOnwardSampleShipmentRelationshipName = "lvocsc_onwardsampleshipment_incident_regardingcase"; XrmFakedRelationship caseOnwardSampleShipmentRelationship = new XrmFakedRelationship("incidentid", "lvocsc_regardingcase", "incident", "lvocsc_onwardsampleshipment");

List entityList = new List() { sourceCase, failingSample, onwardSampleShipment };

fakedOrgSvcContext.Initialize(entityList); fakedOrgSvcContext.AddRelationship(caseFailingSampleRelationshipName, caseFailingSampleRelationship); fakedOrgSvcContext.AddRelationship(caseOnwardSampleShipmentRelationshipName, caseOnwardSampleShipmentRelationship);

AssociateRequest associateRequest1 = new AssociateRequest { Target = sourceCase.ToEntityReference(), RelatedEntities = new EntityReferenceCollection() }; associateRequest1.RelatedEntities.Add(failingSample.ToEntityReference()); associateRequest1.Relationship = new Relationship(caseFailingSampleRelationshipName); fakedOrgSvc.Execute(associateRequest1);

AssociateRequest associateRequest2 = new AssociateRequest { Target = sourceCase.ToEntityReference(), RelatedEntities = new EntityReferenceCollection() }; associateRequest2.RelatedEntities.Add(onwardSampleShipment.ToEntityReference()); associateRequest2.Relationship = new Relationship(caseOnwardSampleShipmentRelationshipName); fakedOrgSvc.Execute(associateRequest2);

fakedOrgSvcContext.ExecutePluginWith(fakedPluginContext);

//Assertions here`

Am I missing something?

jordimontana82 commented 4 years ago

Hi David, the XrmFakedRelationship's default constructor sets the relationship as N:N. Could you try by setting it to OneToMany and see if that works?

The fake relationship really was meant to support the mocking of N:N relationships mostly, and then legacy code using .Associate messages for 1:N relationships.

But going forward, since you can assign records in a 1:N relationships simply via updating records (just populating the referenced record in the lookup field) is much more easier that way, to develop and also to test it, cause there's no need of mocking those relationships that way.

Hope this helps.

dewilliams704 commented 4 years ago

Hey Jordi, thanks for the quick reply. As you can see in the code below, I did try to simply use the lookup field to associate the two:

onwardSampleShipment["lvocsc_regardingcase"] = sourceCase.ToEntityReference();

But it didn't seem to associate them. In the plugin itself, when I call the following method, it does not return any associated records:

 public List<Entity> RetrieveRelatedOnwardSampleShipments(IOrganizationService OrgSvc, Guid caseId, ColumnSet columnSet)

            {

                QueryExpression query= new QueryExpression

                {

                    EntityName = "lvocsc_onwardsampleshipment",

                    ColumnSet = columnSet

                };
                query.Criteria.AddCondition("incidentid", ConditionOperator.Equal, caseId);

                query.AddOrder("createdon", OrderType.Descending);

                EntityCollection results = OrgSvc.RetrieveMultiple(query);

                return results?.Entities.ToList() ?? new List<Entity>();

            }

I feel like I've somehow over complicated things. Even After removing the mocking of the relationships, etc and trying to create the relationship using an EntityReference in the lookup field value, there still seems to be no association.

dewilliams704 commented 4 years ago

I've discovered my issue. When retrieving the related onward sample shipments, I had the condition set to incidentid rather than lvocsc_regardingcase.