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"]);
}
}
}