Komponententests in Office-Add-Ins
Komponententests überprüfen die Funktionalität Ihres Add-Ins, ohne dass Netzwerk- oder Dienstverbindungen erforderlich sind, einschließlich Verbindungen mit der Office-Anwendung. Serverseitiger Code für Komponententests und clientseitiger Code, der dieOffice-JavaScript-APIs nicht aufruft, sind in Office-Add-Ins identisch mit allen Webanwendungen, sodass keine spezielle Dokumentation erforderlich ist. Clientseitiger Code, der die Office-JavaScript-APIs aufruft, ist jedoch schwierig zu testen. Um diese Probleme zu lösen, haben wir eine Bibliothek erstellt, um die Erstellung von Simulierten Office-Objekten in Komponententests zu vereinfachen: Office-Addin-Mock. Die Bibliothek erleichtert das Testen auf folgende Weise:
- Die Office-JavaScript-APIs müssen in einem Webview-Steuerelement im Kontext einer Office-Anwendung (Excel, Word usw.) initialisiert werden, damit sie nicht in den Prozess geladen werden können, in dem Komponententests auf Ihrem Entwicklungscomputer ausgeführt werden. Die Office-Addin-Mock-Bibliothek kann in Ihre Testdateien importiert werden, was das Simulieren von Office-JavaScript-APIs innerhalb des Node.js Prozesses ermöglicht, in dem die Tests ausgeführt werden.
- Die anwendungsspezifischen APIs verfügen über Lade- und Synchronisierungsmethoden , die relativ zu anderen Funktionen und zueinander in einer bestimmten Reihenfolge aufgerufen werden müssen. Darüber hinaus muss die
load
-Methode mit bestimmten Parametern aufgerufen werden, je nachdem, welche Eigenschaften von Office-Objekten später in der zu testierenden Funktion vom Code gelesen werden. Komponententestframeworks sind jedoch inhärent zustandslos, sodass sie nicht aufzeichnen können, obload
odersync
aufgerufen wurde oder welche Parameter anload
übergeben wurden. Die Modellobjekte, die Sie mit der Office-Addin-Mock-Bibliothek erstellen, verfügen über einen internen Zustand, der diese Elemente nachverfolgt. Dadurch können die Pseudoobjekte das Fehlerverhalten tatsächlicher Office-Objekte emulieren. Wenn die getestete Funktion beispielsweise versucht, eine Eigenschaft zu lesen, die nicht zuerst anload
übergeben wurde, gibt der Test einen Fehler zurück, der dem ähnelt, was Office zurückgeben würde.
Die Bibliothek ist nicht von den Office JavaScript-APIs abhängig und kann mit jedem JavaScript-Komponententestframework verwendet werden, z. B.:
In den Beispielen in diesem Artikel wird das Jest-Framework verwendet. Beispiele zur Verwendung des Mocha-Frameworks gibt es auf der Office-Addin-Mock-Startseite.
Voraussetzungen
In diesem Artikel wird davon ausgegangen, dass Sie mit den grundlegenden Konzepten von Komponententests und -mocking, einschließlich des Erstellens und Ausführens von Testdateien, vertraut sind und über einige Erfahrung mit einem Komponententestframework verfügen.
Tipp
Wenn Sie mit Visual Studio arbeiten, empfiehlt es sich, den Artikel Komponententests von JavaScript und TypeScript in Visual Studio zu lesen, um einige grundlegende Informationen zu JavaScript-Komponententests in Visual Studio zu erhalten und dann zu diesem Artikel zurückzukehren.
Installieren des Tools
Öffnen Sie zum Installieren der Bibliothek eine Eingabeaufforderung, navigieren Sie zum Stammverzeichnis Ihres Add-In-Projekts, und geben Sie dann den folgenden Befehl ein.
npm install office-addin-mock --save-dev
Grundlegende Nutzung
Ihr Projekt verfügt über eine oder mehrere Testdateien. (Die Anweisungen für Ihr Testframework und die Beispieltestdateien finden Sie unten in den Beispielen.) Importieren Sie die Bibliothek entweder mit dem
require
Schlüsselwort (keyword) oderimport
in eine beliebige Testdatei, die einen Test einer Funktion enthält, die die Office JavaScript-APIs aufruft, wie im folgenden Beispiel gezeigt.const OfficeAddinMock = require("office-addin-mock");
Importieren Sie das Modul, das die Add-In-Funktion enthält, die Sie mit oder
require
import
Schlüsselwort (keyword) testen möchten. Im folgenden Beispiel wird davon ausgegangen, dass sich Ihre Testdatei in einem Unterordner des Ordners mit den Codedateien Ihres Add-Ins befindet.const myOfficeAddinFeature = require("../my-office-add-in");
Erstellen Sie ein Datenobjekt mit den Eigenschaften und Untereigenschaften, die Sie zum Testen der Funktion simulieren müssen. Im Folgenden finden Sie ein Beispiel für ein Objekt, das die Excel Workbook.range.address-Eigenschaft und die Workbook.getSelectedRange-Methode simuliert. Dies ist nicht das letzte Pseudoobjekt. Stellen Sie sich dies als Seedobjekt vor, das von
OfficeMockObject
zum Erstellen des endgültigen Pseudoobjekts verwendet wird.const mockData = { workbook: { range: { address: "C2:G3", }, getSelectedRange: function () { return this.range; }, }, };
Übergeben Sie das Datenobjekt an den
OfficeMockObject
Konstruktor. Beachten Sie Folgendes zum zurückgegebenenOfficeMockObject
Objekt.- Es handelt sich um ein vereinfachtes Modell eines OfficeExtension.ClientRequestContext-Objekts .
- Das Mockobjekt verfügt über alle Member des Datenobjekts und verfügt auch über Pseudoimplementierungen der
load
Methoden undsync
. - Das Pseudoobjekt imitiert das entscheidende Fehlerverhalten des
ClientRequestContext
Objekts. Wenn die Office-API, die Sie testen, z. B. versucht, eine Eigenschaft zu lesen, ohne zuerst die Eigenschaft zu laden und aufzurufensync
, schlägt der Test mit einem Fehler fehl, der dem ähnelt, was in der Produktionslaufzeit ausgelöst wird: "Fehler, Eigenschaft nicht geladen".
const contextMock = new OfficeAddinMock.OfficeMockObject(mockData);
Hinweis
Die vollständige Referenzdokumentation für den
OfficeMockObject
Typ finden Sie unter Office-Addin-Mock.Fügen Sie in der Syntax Ihres Testframeworks einen Test der Funktion hinzu. Verwenden Sie das
OfficeMockObject
-Objekt anstelle des Objekts, das es simuliert, in diesem Fall dasClientRequestContext
-Objekt. Im Folgenden wird das Beispiel in Jest fortgesetzt. Bei diesem Beispieltest wird davon ausgegangen, dass die zu testende Add-In-Funktion den Namen trägtgetSelectedRangeAddress
, dass sie einClientRequestContext
-Objekt als Parameter akzeptiert und die Adresse des aktuell ausgewählten Bereichs zurückgeben soll. Das vollständige Beispiel finden Sie weiter unten in diesem Artikel.test("getSelectedRangeAddress should return the address of the range", async function () { expect(await getSelectedRangeAddress(contextMock)).toBe("C2:G3"); });
Führen Sie den Test gemäß der Dokumentation des Testframeworks und Ihrer Entwicklungstools aus. In der Regel gibt es eine Package.json-Datei mit einem Skript, das das Testframework ausführt. Wenn z. B. Jest das Framework ist, enthält package.json Folgendes:
"scripts": { "test": "jest", -- other scripts omitted -- }
Um den Test auszuführen, geben Sie Folgendes in einer Eingabeaufforderung im Stammverzeichnis des Projekts ein.
npm test
Beispiele
In den Beispielen in diesem Abschnitt wird Jest mit den Standardeinstellungen verwendet. Diese Einstellungen unterstützen CommonJS-Module. Informationen zum Konfigurieren von Jest und Node.js zur Unterstützung von ECMAScript-Modulen und zur Unterstützung von TypeScript finden Sie in der Jest-Dokumentation . Führen Sie die folgenden Schritte aus, um eines dieser Beispiele auszuführen.
- Erstellen Sie ein Office-Add-In-Projekt für die entsprechende Office-Hostanwendung (z. B. Excel oder Word). Eine Möglichkeit, dies schnell zu tun, ist die Verwendung des Yeoman-Generators für Office-Add-Ins.
- Installieren Sie im Stammverzeichnis des Projekts Jest.
- Installieren Sie das Tool office-addin-mock.
- Erstellen Sie eine Datei genau wie die erste Datei im Beispiel, und fügen Sie sie dem Ordner hinzu, der die anderen Quelldateien des Projekts enthält, die häufig als bezeichnet werden
\src
. - Erstellen Sie einen Unterordner für den Quelldateiordner, und geben Sie ihm einen entsprechenden Namen, z
\tests
. B. . - Erstellen Sie eine Datei genau wie die Testdatei im Beispiel, und fügen Sie sie dem Unterordner hinzu.
- Fügen Sie der Datei package.json ein
test
Skript hinzu, und führen Sie dann den Test aus, wie unter Grundlegende Verwendung beschrieben.
Simulieren der allgemeinen Office-APIs
In diesem Beispiel wird von einem Office-Add-In für jeden Host ausgegangen, der die allgemeinen Office-APIs unterstützt (z. B. Excel, PowerPoint oder Word). Das Add-In verfügt über eines seiner Features in einer Datei namens my-common-api-add-in-feature.js
. Im Folgenden wird der Inhalt der Datei veranschaulicht. Die addHelloWorldText
Funktion legt den Text "Hallo Welt!" auf den aktuell im Dokument ausgewählten Text fest, z. B. auf einen Bereich in Word oder eine Zelle in Excel oder auf ein Textfeld in PowerPoint.
const myCommonAPIAddinFeature = {
addHelloWorldText: async () => {
const options = { coercionType: Office.CoercionType.Text };
await Office.context.document.setSelectedDataAsync("Hello World!", options);
}
}
module.exports = myCommonAPIAddinFeature;
Die Testdatei mit dem Namen my-common-api-add-in-feature.test.js
befindet sich relativ zum Speicherort der Add-In-Codedatei in einem Unterordner. Im Folgenden wird der Inhalt der Datei veranschaulicht. Beachten Sie, dass die Eigenschaft der obersten Ebene ein Office.Context-Objekt istcontext
, sodass das Objekt, das simuliert wird, das übergeordnete Objekt dieser Eigenschaft ist: ein Office-Objekt. Zu diesem Code ist Folgendes anzumerken:
- Der
OfficeMockObject
Konstruktor fügt dem PseudoobjektOffice
nicht alle Office-Enumerationsklassen hinzu, daher muss der Wert, auf denCoercionType.Text
in der Add-In-Methode verwiesen wird, explizit im Seedobjekt hinzugefügt werden. - Da die Office JavaScript-Bibliothek nicht im Knotenprozess geladen wird, muss das
Office
Objekt, auf das im Add-In-Code verwiesen wird, deklariert und initialisiert werden.
const OfficeAddinMock = require("office-addin-mock");
const myCommonAPIAddinFeature = require("../my-common-api-add-in-feature");
// Create the seed mock object.
const mockData = {
context: {
document: {
setSelectedDataAsync: function (data, options) {
this.data = data;
this.options = options;
},
},
},
// Mock the Office.CoercionType enum.
CoercionType: {
Text: {},
},
};
// Create the final mock object from the seed object.
const officeMock = new OfficeAddinMock.OfficeMockObject(mockData);
// Create the Office object that is called in the addHelloWorldText function.
global.Office = officeMock;
/* Code that calls the test framework goes below this line. */
// Jest test
test("Text of selection in document should be set to 'Hello World'", async function () {
await myCommonAPIAddinFeature.addHelloWorldText();
expect(officeMock.context.document.data).toBe("Hello World!");
});
Simulieren der Outlook-APIs
Obwohl die Outlook-APIs streng genommen Teil des allgemeinen API-Modells sind, verfügen sie über eine spezielle Architektur, die um das Mailbox-Objekt herum erstellt wurde. Daher haben wir ein eindeutiges Beispiel für Outlook bereitgestellt. In diesem Beispiel wird davon ausgegangen, dass outlook über eines seiner Features in einer Datei namens verfügt my-outlook-add-in-feature.js
. Im Folgenden wird der Inhalt der Datei veranschaulicht. Die addHelloWorldText
Funktion legt den Text "Hallo Welt!" auf den wert fest, der derzeit im Fenster zum Verfassen von Nachrichten ausgewählt ist.
const myOutlookAddinFeature = {
addHelloWorldText: async () => {
Office.context.mailbox.item.setSelectedDataAsync("Hello World!");
}
}
module.exports = myOutlookAddinFeature;
Die Testdatei mit dem Namen my-outlook-add-in-feature.test.js
befindet sich relativ zum Speicherort der Add-In-Codedatei in einem Unterordner. Im Folgenden wird der Inhalt der Datei veranschaulicht. Beachten Sie, dass die Eigenschaft der obersten Ebene ein Office.Context-Objekt istcontext
, sodass das Objekt, das simuliert wird, das übergeordnete Objekt dieser Eigenschaft ist: ein Office-Objekt. Zu diesem Code ist Folgendes anzumerken:
- Die
host
-Eigenschaft des Pseudoobjekts wird intern von der Modellbibliothek verwendet, um die Office-Anwendung zu identifizieren. Dies ist für Outlook obligatorisch. Es dient derzeit keinem Zweck für andere Office-Anwendungen. - Da die Office JavaScript-Bibliothek nicht im Knotenprozess geladen wird, muss das
Office
Objekt, auf das im Add-In-Code verwiesen wird, deklariert und initialisiert werden.
const OfficeAddinMock = require("office-addin-mock");
const myOutlookAddinFeature = require("../my-outlook-add-in-feature");
// Create the seed mock object.
const mockData = {
// Identify the host to the mock library (required for Outlook).
host: "outlook",
context: {
mailbox: {
item: {
setSelectedDataAsync: function (data) {
this.data = data;
},
},
},
},
};
// Create the final mock object from the seed object.
const officeMock = new OfficeAddinMock.OfficeMockObject(mockData);
// Create the Office object that is called in the addHelloWorldText function.
global.Office = officeMock;
/* Code that calls the test framework goes below this line. */
// Jest test
test("Text of selection in message should be set to 'Hello World'", async function () {
await myOutlookAddinFeature.addHelloWorldText();
expect(officeMock.context.mailbox.item.data).toBe("Hello World!");
});
Simulieren der anwendungsspezifischen Office-APIs
Wenn Sie Funktionen testen, die die anwendungsspezifischen APIs verwenden, stellen Sie sicher, dass Sie den richtigen Objekttyp simulieren. Es gibt zwei Möglichkeiten:
Simulieren sie ein OfficeExtension.ClientRequestObject. Führen Sie dies aus, wenn die getestete Funktion die beiden folgenden Bedingungen erfüllt:
- Es ruft keinen Host auf.
run
-Funktion, z. B. Excel.run. - Es verweist nicht auf eine andere direkte Eigenschaft oder Methode eines Host-Objekts .
- Es ruft keinen Host auf.
Simulieren sie ein Host-Objekt, z. B. Excel oder Word. Gehen Sie dazu vor, wenn die vorherige Option nicht möglich ist.
Beispiele für beide Arten von Tests finden Sie in den folgenden Unterabschnitten.
Hinweis
Die Office-Addin-Mock-Bibliothek unterstützt derzeit keine Mocking von Auflistungstypobjekten, bei denen es sich um objekte in den anwendungsspezifischen APIs handelt, die nach dem Muster *Collection benannt sind, z. B. WorksheetCollection. Wir arbeiten hart daran, diese Unterstützung zur Bibliothek hinzuzufügen.
Simulieren eines ClientRequestContext-Objekts
In diesem Beispiel wird davon ausgegangen, dass ein Excel-Add-In über eines seiner Features in einer Datei namens verfügt my-excel-add-in-feature.js
. Im Folgenden wird der Inhalt der Datei veranschaulicht. Beachten Sie, dass es sich bei um getSelectedRangeAddress
eine Hilfsmethode namens innerhalb des Rückrufs handelt, der an Excel.run
übergeben wird.
const myExcelAddinFeature = {
getSelectedRangeAddress: async (context) => {
const range = context.workbook.getSelectedRange();
range.load("address");
await context.sync();
return range.address;
}
}
module.exports = myExcelAddinFeature;
Die Testdatei mit dem Namen my-excel-add-in-feature.test.js
befindet sich relativ zum Speicherort der Add-In-Codedatei in einem Unterordner. Im Folgenden wird der Inhalt der Datei veranschaulicht. Beachten Sie, dass die Eigenschaft der obersten Ebene ist workbook
, sodass das Objekt, das simuliert wird, das übergeordnete Objekt eines Excel.Workbook
ist: ein ClientRequestContext
-Objekt.
const OfficeAddinMock = require("office-addin-mock");
const myExcelAddinFeature = require("../my-excel-add-in-feature");
// Create the seed mock object.
const mockData = {
workbook: {
range: {
address: "C2:G3",
},
// Mock the Workbook.getSelectedRange method.
getSelectedRange: function () {
return this.range;
},
},
};
// Create the final mock object from the seed object.
const contextMock = new OfficeAddinMock.OfficeMockObject(mockData);
/* Code that calls the test framework goes below this line. */
// Jest test
test("getSelectedRangeAddress should return address of selected range", async function () {
expect(await myOfficeAddinFeature.getSelectedRangeAddress(contextMock)).toBe("C2:G3");
});
Simulieren eines Hostobjekts
In diesem Beispiel wird davon ausgegangen, dass ein Word-Add-In über eines seiner Features in einer Datei namens verfügtmy-word-add-in-feature.js
. Im Folgenden wird der Inhalt der Datei veranschaulicht.
const myWordAddinFeature = {
insertBlueParagraph: async () => {
return Word.run(async (context) => {
// Insert a paragraph at the end of the document.
const paragraph = context.document.body.insertParagraph("Hello World", Word.InsertLocation.end);
// Change the font color to blue.
paragraph.font.color = "blue";
await context.sync();
});
}
}
module.exports = myWordAddinFeature;
Die Testdatei mit dem Namen my-word-add-in-feature.test.js
befindet sich relativ zum Speicherort der Add-In-Codedatei in einem Unterordner. Im Folgenden wird der Inhalt der Datei veranschaulicht. Beachten Sie, dass die Eigenschaft der obersten Ebene ein ClientRequestContext
-Objekt istcontext
, sodass das Objekt, das simuliert wird, das übergeordnete Objekt dieser Eigenschaft ist: ein Word
-Objekt. Zu diesem Code ist Folgendes anzumerken:
- Wenn der
OfficeMockObject
Konstruktor das letzte Pseudoobjekt erstellt, wird sichergestellt, dass das untergeordneteClientRequestContext
Objektsync
über - undload
-Methoden verfügt. - Der
OfficeMockObject
Konstruktor fügtrun
dem PseudoobjektWord
keine Funktion hinzu, daher muss sie explizit im Seedobjekt hinzugefügt werden. - Der
OfficeMockObject
Konstruktor fügt dem PseudoobjektWord
nicht alle Word Enumerationsklassen hinzu, sodass der Wert, auf denInsertLocation.end
in der Add-In-Methode verwiesen wird, explizit im Seedobjekt hinzugefügt werden muss. - Da die Office JavaScript-Bibliothek nicht im Knotenprozess geladen wird, muss das
Word
Objekt, auf das im Add-In-Code verwiesen wird, deklariert und initialisiert werden.
const OfficeAddinMock = require("office-addin-mock");
const myWordAddinFeature = require("../my-word-add-in-feature");
// Create the seed mock object.
const mockData = {
context: {
document: {
body: {
paragraph: {
font: {},
},
// Mock the Body.insertParagraph method.
insertParagraph: function (paragraphText, insertLocation) {
this.paragraph.text = paragraphText;
this.paragraph.insertLocation = insertLocation;
return this.paragraph;
},
},
},
},
// Mock the Word.InsertLocation enum.
InsertLocation: {
end: "end",
},
// Mock the Word.run function.
run: async function(callback) {
await callback(this.context);
},
};
// Create the final mock object from the seed object.
const wordMock = new OfficeAddinMock.OfficeMockObject(mockData);
// Define and initialize the Word object that is called in the insertBlueParagraph function.
global.Word = wordMock;
/* Code that calls the test framework goes below this line. */
// Jest test set
describe("Insert blue paragraph at end tests", () => {
test("color of paragraph", async function () {
await myWordAddinFeature.insertBlueParagraph();
expect(wordMock.context.document.body.paragraph.font.color).toBe("blue");
});
test("text of paragraph", async function () {
await myWordAddinFeature.insertBlueParagraph();
expect(wordMock.context.document.body.paragraph.text).toBe("Hello World");
});
})
Hinweis
Die vollständige Referenzdokumentation für den OfficeMockObject
Typ finden Sie unter Office-Addin-Mock.
Siehe auch
- Installationspunkt der Npm-Seite von Office-Addin-Mock .
- Das Open Source Repository ist Office-Addin-Mock.
- Jest
- Mokka
- Jasmin
Office Add-ins