How do you write a class for a Dynamics CRM form in TypeScript that is testable?
By testable, I mean a non-static class that can be instantiated and passed a mock Xrm object.
My current approach is something like this, but it has limitations (which I explain):
export class Contact {
Xrm: Xrm.XrmStatic;
constructor(xrm?: Xrm.XrmStatic) {
this.Xrm = xrm;
}
onLoad(): void {
if (this.Xrm) { Xrm = this.Xrm; }
// ...
}
}
Firstly, the Contact
class is exported so that can be referenced by a CRM form. CRM can't instantiate an object before calling it's functions, so to call these methods I use Contact.prototype.onLoad in the CRM form designer.
My test looks like this:
beforeEach(function () {
this.XrmMock = new XrmStaticMock();
this.contact = new Contact(this.XrmMock);
this.contact.onLoad();
}
it('does stuff', function () {
// ...
}
The test is able to instantiate Contact
and pass XrmMock
to the constructor. Subsequently when onLoad()
is called, it evaluates if (this.Xrm)
to true, and uses XrmMock
. Conversely, when Contact.prototype.onLoad()
is called from within CRM, (this.Xrm)
is false because Contact
has never been instantiated. Therefore any reference to Xrm
within onLoad()
uses the default Xrm
namespace (which is what we want). We want this because when a CRM form is opened, the real Xrm
dependency is loaded by the browser.
The limitation here is having to write a conditional check in every method which wants to use the Xrm
dependency. How can this be overcome?
Here's a link to documentation on the Xrm.Page object model. My classes and Xrm mock are written using @types/xrm.
I appreciate I'm asking multiple questions here, if you think you can guide me to writing a more specific question, please let me know :)
Aucun commentaire:
Enregistrer un commentaire