OfficeDev / OfficeDev/Office-Addin-Scripts

Unit testing Word Office Add-ins

Open
#781 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
194
Forks
117
Avg merge
1d 32m
Merged PRs (30d)
2

Description

Hello everyone,

My team and I are working on an Office Word Add-in which interacts with the document to insert text, images, tables, etc.

We've implemented a few helper functions to make those insertions with the Word JS API. Here's how one looks like:

export const insertTagIntoDoc = async (tag: Tag) => {
    const { path, type } = tag;

    try {
        await Word.run(async context => {
            const selectionRange = context.document.getSelection();
            let insertedContent: Word.Range | Word.InlinePicture | null = null;

            // Insert content into the document
            if (type === 'text') {
                insertedContent = selectionRange.insertText(`{{ ${path} }}`, Word.InsertLocation.replace);
            } else {
                insertedContent = selectionRange.insertInlinePictureFromBase64(tag.base64, Word.InsertLocation.replace);
                insertedContent.altTextDescription = tag.altText ?? '';
                if (tag.height) {
                    insertedContent.height = tag.height;
                }
                if (tag.width) {
                    insertedContent.width = tag.width;
                }
            }

            // Move cursor to the end of the inserted content
            insertedContent.select('End');

            await context.sync();
        });
    } catch (error) {
        console.log(error)
    }
};

However, it is not clear to us how to unit test those functions with the office-addin-mock. We know there is a section in the documentation about using that mock but it is very succinct and we don't know how to apply it to our use case.

More specifically, it's not clear what should be added the the mock object data and how to test that after calling the insertTagIntoDoc function, the document contains the data as expected, in this case, either some text or an image. Also, we want to test that the inserted context replace the current selection in the document, and that the cursor is move to the end of the inserted content.

import { OfficeMockObject } from 'office-addin-mock';

// Create the seed mock object
export const mockData = {
    context: {
        document: {
            // what to add here?
        },
    },
    InsertLocation: {
        replace: 'replace',
        before: 'before',
        after: 'after',
    },
    async run(callback: (context: unknown) => Promise<void>) {
        await callback(this.context);
    },
};

// Create the final mock object from the seed object
export const wordMock = new OfficeMockObject(mockData);

// Define and initialize the Word object
global.Word = wordMock as unknown as typeof Word;

Here's what we get when log the wordMock object in the console in our test:

it('should insert an image tag', async () => {
    await insertTagIntoDoc(imgTag);

    console.log(wordMock);

    // TODO: check document data
});
OfficeMockObject {
  _properties: Map(2) {
    'context' => OfficeMockObject {
      _properties: [Map],
      _loaded: false,
      _host: undefined,
      _value: 'Error, property was not loaded',
      _valueBeforeLoaded: undefined,
      _isObject: true,
      document: [OfficeMockObject]
    },
    'InsertLocation' => OfficeMockObject {
      _properties: [Map],
      _loaded: false,
      _host: undefined,
      _value: 'Error, property was not loaded',
      _valueBeforeLoaded: undefined,
      _isObject: true,
      replace: 'Error, property was not loaded',
      before: 'Error, property was not loaded',
      after: 'Error, property was not loaded'
    }
  },
  _loaded: false,
  _host: undefined,
  _value: 'Error, property was not loaded',
  _valueBeforeLoaded: undefined,
  context: OfficeMockObject {
    _properties: Map(1) { 'document' => [OfficeMockObject] },
    _loaded: false,
    _host: undefined,
    _value: 'Error, property was not loaded',
    _valueBeforeLoaded: undefined,
    _isObject: true,
    document: OfficeMockObject {
      _properties: Map(0) {},
      _loaded: false,
      _host: undefined,
      _value: 'Error, property was not loaded',
      _valueBeforeLoaded: undefined,
      _isObject: true
    }
  },
  InsertLocation: OfficeMockObject {
    _properties: Map(3) {
      'replace' => [OfficeMockObject],
      'before' => [OfficeMockObject],
      'after' => [OfficeMockObject]
    },
    _loaded: false,
    _host: undefined,
    _value: 'Error, property was not loaded',
    _valueBeforeLoaded: undefined,
    _isObject: true,
    replace: 'Error, property was not loaded',
    before: 'Error, property was not loaded',
    after: 'Error, property was not loaded'
  },
  run: [AsyncFunction: run]
}

Thanks for your help.

Greg

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the office-addin-mock documentation section referenced in the issue and inspect the OfficeMockObject seed data around context.document. Then review insertTagIntoDoc and the example test to determine which mock methods and values need documenting. Done means the docs explain how to model insertion, replacement, selection, and cursor behavior for text and images.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
developer-experience, testing-qa
Issue type
Documentation
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.