Search code examples
outlookjestjsmockingoffice-jsoutlook-web-addins

Mocking properties using office-addin-mock yields "Error, property was not loaded"


Consider the following Greeter.tsx React component:

import React from "react";

export const Greeter: React.FC = () => {
  return <p>Hello, {Office.context.mailbox.userProfile.displayName}</p>;
};

and the following Greeter.test.tsx test suite:

import React from "react";
import { render } from "@testing-library/react";
import { OfficeMockObject } from "office-addin-mock";
import { Greeter } from "./Greeter";

const mockData = {
  context: {
    mailbox: {
      userProfile: {
        displayName: "John Doe",
      },
    },
  },
};

const officeMock = new OfficeMockObject(mockData);
global.Office = officeMock;

describe("Greeter", () => {
  it("greets the current user", () => {
    const { getByText } = render(<Greeter />);

    expect(getByText(/Hello, John Doe/)).toBeInTheDocument();
  });
});

My test fails because the Office.context.mailbox.userProfile.displayName property yields the string Error, property was not loaded.

Inspecting the mock object further, it looks like my intended value is indeed saved in the mock object but not used.

State of the Office object

I did some further digging in the office-addin-mock module and it seems that a prior sync is needed to set the this.loaded property to true and therefore assigning this.valueBeforeLoaded to this.value. Here's an excerpt from the office-addin-mock package:

async sync() {
  this.properties.forEach(async (property: OfficeMockObject, key: string) => {
    await property.sync();
    this.updatePropertyCall(key);
  });
  if (this.loaded) {
    this.value = this.valueBeforeLoaded;
  }
}

My understanding is that context.sync is a concept prevalent in Excel web add-in development, but not Outlook. However, at this point I stopped the investigation as it's probably easier for Microsoft to dig further. Any assistance is much appreciated!


Solution

  • Thanks for reporting with so many details! I created an issue of this bug in our repo to track it: Office-Addin-Scripts Issues

    This is indeed a bug in our code. What is happening is that properties values assigned in the constructor of OfficeMockObject are not working for Outlook. A workaround, while the solution is not implemented, is to assign the variable value after the constructor:

    officeMock.context.mailbox.userProfile.displayName = "John Doe";