using System; using Microsoft.Xrm.Sdk; using NUnit.Framework; using Moq; namespace LucasDemoCrm { /// /// This class holds the interface business logic we want to test /// public class MockDemo { /// /// Creates a new account with a given name using the supplied organization service /// /// account name /// organization service /// id of the new account public static Guid CreateCrmAccount(string accountName, IOrganizationService service) { Entity account = new Entity("account"); account["name"] = accountName; Guid newId = service.Create(account); return newId; } /// /// Creates a new account with a given name and then creates a follow-up task linked to the account /// /// account name /// organization service public static void CreateCrmAccount2(string accountName, IOrganizationService service) { //create the account Entity account = new Entity("account"); account["name"] = accountName; Guid newId = service.Create(account); //get the account number account = service.Retrieve("account", newId, new Microsoft.Xrm.Sdk.Query.ColumnSet(new string[]{"name","accountid","accountnumber"})); string accountNumber = account["accountnumber"].ToString(); //create the task Entity task = new Entity("task"); task["subject"] = "Finish account set up for " + accountName + " - " + accountNumber; task["regardingobjectid"] = new Microsoft.Xrm.Sdk.EntityReference("account", newId); service.Create(task); } } /// /// This class holds our test methods /// [TestFixture] public class MockDemoTest { /// /// Tests the CreateCrmAccount method /// [Test] public void CreateCrmAccount() { //ARRANGE - set up everything our test needs //first - set up a mock service to act like the CRM organization service var serviceMock = new Mock(); IOrganizationService service = serviceMock.Object; //next - set a name for our fake account record to create string accountName = "Lucas Demo Company"; //next - create a guid that we want our mock service Create method to return when called Guid idToReturn = Guid.NewGuid(); //next - create an entity object that will allow us to capture the entity record that is passed to the Create method Entity actualEntity = new Entity(); //finally - tell our mock service what to do when the Create method is called serviceMock.Setup(t => t.Create(It.IsAny())) //when Create is called with any entity as an invocation parameter .Returns(idToReturn) //return the idToReturn guid .Callback(s => actualEntity = s); //store the Create method invocation parameter for inspection later //ACT - do the thing(s) we want to test //call the CreateCrmAccount method like usual, but supply the mock service as an invocation parameter Guid actualGuid = MockDemo.CreateCrmAccount(accountName, service); //ASSERT - verify the results are correct //verify the entity created inside the CreateCrmAccount method has the name we supplied Assert.AreEqual(accountName, actualEntity["name"]); //verify the guid returned by the CreateCrmAccount is the same guid the Create method returns Assert.AreEqual(idToReturn, actualGuid); } /// /// Tests the CreateCrmAccount2 method /// [Test] public void CreateCrmAccount2() { //ARRANGE - set up everything our test needs //first - set up a mock service to act like the CRM organization service var serviceMock = new Mock(); IOrganizationService service = serviceMock.Object; //next - set a name and account number for our fake account record to create string accountName = "Lucas Demo Company"; string accountNumber = "LPA1234"; //next - create a guid that we want our mock service Create method to return when called Guid idToReturn = Guid.NewGuid(); //next - create an object that will allow us to capture the account object that is passed to the Create method Entity createdAccount = new Entity(); //next - create an entity object that will allow us to capture the task object that is passed to the Create method Entity createdTask = new Entity(); //next - create an mock account record to pass back to the Retrieve method Entity mockReturnedAccount = new Entity("account"); mockReturnedAccount["name"] = accountName; mockReturnedAccount["accountnumber"] = accountNumber; mockReturnedAccount["accountid"] = idToReturn; mockReturnedAccount.Id = idToReturn; //finally - tell our mock service what to do when the CRM service methods are called //handle the account creation serviceMock.Setup(t => t.Create(It.Is(e => e.LogicalName.ToUpper() == "account".ToUpper()))) //only match an entity with a logical name of "account" .Returns(idToReturn) //return the idToReturn guid .Callback(s => createdAccount = s); //store the Create method invocation parameter for inspection later //handle the task creation serviceMock.Setup(t => t.Create(It.Is(e => e.LogicalName.ToUpper() == "task".ToUpper()))) //only match an entity with a logical name of "task" .Returns(Guid.NewGuid()) //can return any guid here .Callback(s => createdTask = s); //store the Create method invocation parameter for inspection later //handle the retrieve account operation serviceMock.Setup(t => t.Retrieve( It.Is(e => e.ToUpper() == "account".ToUpper()), It.Is(e => e == idToReturn), It.IsAny()) ) //here we match on logical name of account and the correct id .Returns(mockReturnedAccount); //ACT - do the thing(s) we want to test //call the CreateCrmAccount2 method like usual, but supply the mock service as an invocation parameter MockDemo.CreateCrmAccount2(accountName, service); //ASSERT - verify the results are correct //verify the entity created inside the CreateCrmAccount method has the name we supplied Assert.AreEqual(accountName, createdAccount["name"]); //verify task regardingobjectid is the same as the id we returned upon account creation Assert.AreEqual(idToReturn, ((Microsoft.Xrm.Sdk.EntityReference)createdTask["regardingobjectid"]).Id); Assert.AreEqual("Finish account set up for " + accountName + " - " + accountNumber, (string)createdTask["subject"]); } } }