New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[All Hosts] (testing) How to use the Office mocking library #3079
Conversation
Docs Build status updates of commit 8e25720:
|
File | Status | Preview URL | Details |
---|---|---|---|
docs/testing/unit-testing.md | View | Details | |
docs/testing/test-debug-office-add-ins.md | ✅Succeeded | View | |
docs/toc.yml | ✅Succeeded | View |
docs/testing/unit-testing.md
- Line 14, Column 79: [Warning: file-not-found - See documentation]
Invalid file link: '../develop/understanding-the-javascript-api-for-office'.
- Line 14, Column 231: [Warning: file-not-found - See documentation]
Invalid file link: '../develop/application-specific-api-model'.
- Line 14, Column 292: [Warning: file-not-found - See documentation]
Invalid file link: '../develop/application-specific-api-model'.
- Line 232, Column 52: [Warning: file-not-found - See documentation]
Invalid file link: 's/javascript/api/excel'.
For more details, please refer to the build report.
If you see build warnings/errors with permission issues, it might be due to single sign-on (SSO) enabled on Microsoft's GitHub organizations. Please follow instructions here to re-authorize your GitHub account to Docs Build.
Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report.
Note: Your PR may contain errors or warnings unrelated to the files you changed. This happens when external dependencies like GitHub alias, Microsoft alias, cross repo links are updated. Please use these instructions to resolve them.
For any questions, please:
- Try searching the docs.microsoft.com contributor guides
- Post your question in the Docs support channel
Docs Build status updates of commit 35dbde6:
|
File | Status | Preview URL | Details |
---|---|---|---|
docs/testing/unit-testing.md | View | Details | |
docs/testing/test-debug-office-add-ins.md | ✅Succeeded | View | |
docs/toc.yml | ✅Succeeded | View |
docs/testing/unit-testing.md
- Line 14, Column 79: [Warning: file-not-found - See documentation]
Invalid file link: '../develop/understanding-the-javascript-api-for-office'.
For more details, please refer to the build report.
If you see build warnings/errors with permission issues, it might be due to single sign-on (SSO) enabled on Microsoft's GitHub organizations. Please follow instructions here to re-authorize your GitHub account to Docs Build.
Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report.
Note: Your PR may contain errors or warnings unrelated to the files you changed. This happens when external dependencies like GitHub alias, Microsoft alias, cross repo links are updated. Please use these instructions to resolve them.
For any questions, please:
- Try searching the docs.microsoft.com contributor guides
- Post your question in the Docs support channel
Docs Build status updates of commit 2ca7bb9: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
docs/testing/unit-testing.md
Outdated
> [!NOTE] | ||
> Full reference documentation for the `OfficeMockObject` type is at [Office-Addin-Mock](https://github.com/OfficeDev/Office-Addin-Scripts/tree/master/packages/office-addin-mock). | ||
|
||
1. In the syntax of your test framework, add a test of the function, but use the `OfficeMockObject` object in place of the object that it mocks, in this case the `ClientRequestContext` object. The following continues the example in Jest. This example test assumes that the add-in function that is being tested is called `getSelectedRangeAddress`, that it takes a `ClientRequestContext` object as a parameter, and that it is intended to return the address of the currently selected range. The full example is at [Mocking a ClientRequestContext object](#mocking-a-clientrequestcontext-object). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"being tested is called" -> "being tested called"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's right as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with millerds. I think adding the "is" makes the whole sentence ungrammatical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Rick-Kirkham! This is looking good. It's exciting to finally see this feature come to life.
I left some IA suggestions. I can do a more thorough review afterwards.
npm test | ||
``` | ||
|
||
## Examples |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about moving these example setup steps above the "Basic usage" section? I think that preempts questions like "what test file do I add the require
statement to". It also gets people to a working version of unit tests faster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about moving these example setup steps above the "Basic usage" section? I think that preempts questions like "what test file do I add the
require
statement to". It also gets people to a working version of unit tests faster.
I'm not keen on separating the example setup from the Examples section. Understanding what a test file is is part of the prerequisites. To address your concerns, I've added info to the Prerequisites section and the first step of the Basic usage section.
docs/testing/unit-testing.md
Outdated
- The Office JavaScript APIs must initialize in a webview control in the context of an Office application (Excel, Word, etc.), so they cannot be loaded in the process in which unit tests run on your development computer. | ||
- Some unit testing frameworks require that mock objects emulate all the members of the object type that is being mocked, which isn't feasible for the Office JavaScript APIs because some object types have over a hundred members. | ||
- Unit testing frameworks are stateless, which makes it difficult to test the [application-specific APIs](../develop/understanding-the-javascript-api-for-office.md#api-models) in the Office JavaScript APIs, because they have methods [load()](../develop/application-specific-api-model.md#load) and [sync()](../develop/application-specific-api-model.md#sync) that must be called in a particular order relative to other functions and to each other. | ||
|
||
To solve these problems, we have created a library to simplify the creation of mock Office objects in unit tests: [Office-Addin-Mock](https://github.com/OfficeDev/Office-Addin-Scripts/tree/master/packages/office-addin-mock). | ||
|
||
The library doesn't depend on the Office JavaScript APIs and it can be used with any JavaScript unit testing framework, including the following among others: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this explanation of why unit testing the Office JS library is hard. Is there a way to frame this list as a set of solutions Office-Addin-Mock provides? So, instead of saying load
/sync
is hard to test, we say that the mock library makes that easy to test? I also think that'll align well with your prerequisite that readers already be familiar with unit testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rewrote the first and 3rd bullets. Consulting with SMEs about the middle one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deleted middle bullet. What it referred to is not really anything to do with the Office-Addin-Mock.
docs/testing/unit-testing.md
Outdated
- The mock object will mimic crucial error behavior of the `ClientRequestContext` object. For example, if the Office API you are testing tries to read a property without first loading the property and calling `sync()`, then the test will fail with an error similar to what would be thrown in production runtime: "Error, property not loaded". | ||
|
||
```javascript | ||
const contextMock = new OfficeMockObject.OfficeMockObject(mockData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't see this creation pattern in the linked docs. I saw const wordMock = new officeAddinMock.OfficeMockObject(WordMockData);
and const officeMock = new OfficeMockObject(PowerPointMockData);
. This confused me. Should that first example have a capital "O"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad. I forgot to add the following to the PR description. I'll add it now.
NOTE TO REVIEWERS: There will be cross-links between this article and the Readme of the repo for Office-Addin-Mock. So, the content of the two has to be coordinated and made consistent. There's no practical way to do that until after this article is close to finalized. Then there will be a separate PR for the the Readme. Nothing will be published until both documents are done and mutually consistent.
docs/testing/unit-testing.md
Outdated
module.exports = myExcelAddinFeature; | ||
``` | ||
|
||
The test file, named `my-excel-add-in-feature.test.js` is in a subfolder, relative to the location of the add-in code file. The following shows the contents of the file. Note that the top level property is `workbook`, so the object that is being mocked is the parent of an `Excel.workbook`: a `ClientRequestContext` object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe "an Excel.workbook
" should either be "an Excel.Workbook
" (if we're referring to the object type) or "Excel.workbook
" (if we're referring to the host-object property).
docs/testing/unit-testing.md
Outdated
> [!NOTE] | ||
> Full reference documentation for the `OfficeMockObject` type is at [Office-Addin-Mock](https://github.com/OfficeDev/Office-Addin-Scripts/tree/master/packages/office-addin-mock). | ||
|
||
1. In the syntax of your test framework, add a test of the function, but use the `OfficeMockObject` object in place of the object that it mocks, in this case the `ClientRequestContext` object. The following continues the example in Jest. This example test assumes that the add-in function that is being tested is called `getSelectedRangeAddress`, that it takes a `ClientRequestContext` object as a parameter, and that it is intended to return the address of the currently selected range. The full example is at [Mocking a ClientRequestContext object](#mocking-a-clientrequestcontext-object). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's right as is.
Docs Build status updates of commit ac3c81b: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
Docs Build status updates of commit ed20631: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
Docs Build status updates of commit 123f4dc: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Rick-Kirkham! I added some comments and suggestions for your consideration.
docs/testing/unit-testing.md
Outdated
Unit tests check your add-in's functionality without requiring network or service connections, including connections to the Office application. Unit testing server-side code, and client-side code that does *not* call the [Office JavaScript APIs](../develop/understanding-the-javascript-api-for-office.md), is the same in Office Add-ins as it is in any web application, so it requires no special documentation. But client-side code that calls the Office JavaScript APIs is challenging to test. To solve these problems, we have created a library to simplify the creation of mock Office objects in unit tests: [Office-Addin-Mock](https://www.npmjs.com/package/office-addin-mock). The library makes testing easier in the following ways: | ||
|
||
- The Office JavaScript APIs must initialize in a webview control in the context of an Office application (Excel, Word, etc.), so they cannot be loaded in the process in which unit tests run on your development computer. The Office-Addin-Mock library can be imported into your test files, which enables the mocking of Office JavaScript APIs inside the node.js process in which the tests run. | ||
- Unit testing frameworks are stateless, which makes it difficult to test the [application-specific APIs](../develop/understanding-the-javascript-api-for-office.md#api-models) in the Office JavaScript APIs, because they have methods [load](../develop/application-specific-api-model.md#load) and [sync](../develop/application-specific-api-model.md#sync) that must be called in a particular order relative to other functions and to each other. The mock objects that you create with the Office-Addin-Mock library automatically have mock implementations of `load` and `sync`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion to reframe the challenge in terms of Office JS, instead of the unit testing "ideals".
- Unit testing frameworks are stateless, which makes it difficult to test the [application-specific APIs](../develop/understanding-the-javascript-api-for-office.md#api-models) in the Office JavaScript APIs, because they have methods [load](../develop/application-specific-api-model.md#load) and [sync](../develop/application-specific-api-model.md#sync) that must be called in a particular order relative to other functions and to each other. The mock objects that you create with the Office-Addin-Mock library automatically have mock implementations of `load` and `sync`. | |
- The [application-specific APIs](../develop/understanding-the-javascript-api-for-office.md#api-models) in the Office JavaScript APIs are difficult to test because the [load](../develop/application-specific-api-model.md#load) and [sync](../develop/application-specific-api-model.md#sync) methods create complex states. The mock objects that you create with the Office-Addin-Mock library automatically have mock implementations of `load` and `sync`. This lets you control the state of the unit test environment. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm researching this with the SMEs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After consulting with SMEs, I've rewritten this bullet to clarify what it is saying.
docs/testing/unit-testing.md
Outdated
In some scenarios, efficient testing requires that mock objects be created or modified at runtime; that is, while the tests are running. The following are examples: | ||
|
||
- The function that is being tested behaves differently when called a second time, from how it behaves when first called. You need to first test the function with one mock object, then change this mock object and test the function again with the changed mock object. | ||
- You need to test a function against multiple arguments quickly. For example, you need to test a function with a mock object that has a color property and then test the function again with a mock object that has a text property, but is otherwise identical to the original mock object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unclear why "quickly" is a factor in the tests. It seems like the scenario is just editing the same mock object after construction.
docs/testing/unit-testing.md
Outdated
rangeMock.setMock("address", "G6:K9"); | ||
``` | ||
|
||
- `OfficeMockObject.addMockFunction` adds a mock function to a `OfficeMockObject` object. If the function parameter isn't used, an empty function is created. The following is an example: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a little confusing to read about the empty parameter case before seeing an example that doesn't use it. Maybe pull that line out as a note that follows the sample code?
docs/testing/unit-testing.md
Outdated
- `OfficeMockObject.addMock` adds a new `OfficeMockObject` object as a property to an existing one and gives it a name. It would have the minimum members that all `OfficeMockObject` have, such as `load` and `sync`. Additional members can be added with the `setMock` and `addMockFunction` methods. The following is an example: | ||
|
||
```javascript | ||
workbookMock.addMock("range"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this adding a mock property called "range" to the mock workbook? I'm confused because this doesn't map to my mental picture of the Excel object model.
Co-authored-by: Alex Jerabek <38896772+AlexJerabek@users.noreply.github.com>
Co-authored-by: Alex Jerabek <38896772+AlexJerabek@users.noreply.github.com>
Docs Build status updates of commit 043f3ab: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
Docs Build status updates of commit 043f3ab: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
Co-authored-by: Alex Jerabek <38896772+AlexJerabek@users.noreply.github.com>
Co-authored-by: Alex Jerabek <38896772+AlexJerabek@users.noreply.github.com>
Docs Build status updates of commit c1b5e3a: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
Co-authored-by: Alex Jerabek <38896772+AlexJerabek@users.noreply.github.com>
Docs Build status updates of commit 2594783: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
Co-authored-by: Alex Jerabek <38896772+AlexJerabek@users.noreply.github.com>
Docs Build status updates of commit f80b9c8: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
Co-authored-by: Alex Jerabek <38896772+AlexJerabek@users.noreply.github.com>
Co-authored-by: Alex Jerabek <38896772+AlexJerabek@users.noreply.github.com>
Docs Build status updates of commit 0517d94: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
Docs Build status updates of commit 3d731cd: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
Co-authored-by: Alex Jerabek <38896772+AlexJerabek@users.noreply.github.com>
Docs Build status updates of commit 8fb72e5: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
Docs Build status updates of commit b32b0c6: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
Docs Build status updates of commit 26b52aa: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
Docs Build status updates of commit 7c8519b: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! I left a couple minor comments, but I don't need to re-review unless there's a drastic change.
Co-authored-by: Alex Jerabek <38896772+AlexJerabek@users.noreply.github.com>
Docs Build status updates of commit d420eb4: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
Docs Build status updates of commit c5bf511: ✅ Validation status: passed
For more details, please refer to the build report. Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report. For any questions, please:
|
[All Hosts] (testing) How to use the Office mocking library (#3079)
Fixes 1611
Fixes 584
Note to reviewers: More detailed examples in the last section of the article will be part of a Phase 2 PR in a future quarter.
NOTE TO REVIEWERS: There will be cross-links between this article and the Readme of the repo for Office-Addin-Mock. So, the content of the two has to be coordinated and made consistent. There's no practical way to do that until after this article is close to finalized. Then there will be a separate PR for the the Readme. Nothing will be published until both documents are done and mutually consistent.