-
Notifications
You must be signed in to change notification settings - Fork 100
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
OfficeMockObject cannot mock NamedItemCollection #729
Comments
Thanks for reporting this. It looks like there are 3 different issues with the mock package here.
|
@HarryPi @millerds any workaround for this issue, this is happening for me also getting
|
@ramzitannous that is not the same thing. It's also incomplete . . . you aren't mocking the whole office-js path. On top of that I think your resulting json structure doesn't actually include an element named "items" . . . you just assigned a variable named items as part of an object named "areas" without giving it a property name in the object. Look at https://learn.microsoft.com/en-us/office/dev/add-ins/testing/unit-testing for some usage examples. |
@millerds this pattern is needed for range area testing for ex. |
The original comment about collections is a currently limitation that needs to be addressed. Your error, however, is not the same thing even if you are trying to accomplish the same type of testing. Even if support for collects were there, you would be hitting your error because your mock structure above the collection isn't complete and the collection structure you are creating doesn't match the officejs collection structure (which is what you are trying to mock). |
@millerds the structure I'm mocking is exactly like what sheet.getRanges() returns, can you help and show what is wrong in the above code ? |
OK . . . looks like I was mistaken. I thought that the way you were building the structure would leave an anonymous reference to the item collection, but apparently the variable name is keep and used at the property name. It's still just a fragment of the full api structure that would be used in the actual code. The error you getting is different because you're trying to load a property of one of the items of the collection which doesn't exist in the mock object created from the data object. In any case . . . there isn't a workaround. The Mock object doesn't handle collections/arrays and so when parsing out the data input it stops going down at the array and moves onto the next property. This is a limitation of the current mock object. We have a work item on our back log to improve this. |
@millerds is there a timeline for implementing this ? |
We don't comment on timelines. |
It appears that the For example: const mockData = {
context: {
document: {
body: {
fields: {
items: [
{
code: " DATE \\* MERGEFORMAT ",
result: '{"hyperlink":"","isEmpty":false,"style":"Normal","styleBuiltIn":"Normal","text":"23/10/2024"}',
},
{
code: " SECTION \\* MERGEFORMAT ",
result: '{"hyperlink":"","isEmpty":false,"style":"Normal","styleBuiltIn":"Normal","text":"2"}',
}
]
},
},
},
},
run: async function (callback) {
return await callback(this.context)
},
}
const mock = new OfficeMockObject(mockData, OfficeApp.Word) When the mock object is created, the A solution that works for me is to use a dictionary like structure. For example: const mockData = {
context: {
document: {
body: {
fields: {
items: {
0: {
code: " DATE \\* MERGEFORMAT ",
result: '{"hyperlink":"","isEmpty":false,"style":"Normal","styleBuiltIn":"Normal","text":"23/10/2024"}',
},
1: {
code: " SECTION \\* MERGEFORMAT ",
result: '{"hyperlink":"","isEmpty":false,"style":"Normal","styleBuiltIn":"Normal","text":"2"}',
},
length: 2,
},
},
},
},
},
run: async function (callback) {
return await callback(this.context)
},
}
const mock = new OfficeMockObject(mockData, OfficeApp.Word) Now when accessing The next problem is with the example javascript in the documentation, such as this One solution to the above problem is to "monkey patch" the if (!OfficeMockObject.prototype._load) {
OfficeMockObject.prototype._load = OfficeMockObject.prototype.load
OfficeMockObject.prototype.load = function (propertyArgument: string | string[] | ObjectData) {
if (propertyArgument instanceof OfficeMockObject) {
const mock = propertyArgument as OfficeMockObject
return mock._load("*")
} else if (
typeof propertyArgument === "undefined" ||
typeof propertyArgument === "string" ||
Array.isArray(propertyArgument)
) {
// access private fields of OfficeMockObject ...
const mockItemsObj = { ...this["items"] }
const properties = mockItemsObj._properties
if (!properties) {
// does not have an items property
return this._load(propertyArgument)
} else {
const mockLengthObj = { ...properties.get("length") }
const length = mockLengthObj._valueBeforeLoaded ? (mockLengthObj._valueBeforeLoaded as number) : 0
if (typeof propertyArgument === "undefined") {
return this._load("*")
} else {
const names = Array.isArray(propertyArgument)
? (propertyArgument as string[]).filter((name) => name.trim() !== "items")
: propertyArgument?.split(",").filter((name) => name.trim() !== "items")
const indices = [...Array(length).keys()]
const paths = ["items"].concat(
indices.flatMap((index) => names.map((name) => `items/${index}/${name.trim()}`)),
)
return this._load(paths)
}
}
} else {
return this._load(propertyArgument)
}
}
} With the patch in place, the example code will now work as expected, with the |
Hi, When you have any information regarding this, we would be very curious about the development process. |
@asparrowhawk Thank you very much, your monkey patch works fine for us. |
Prerequisites
Please answer the following questions before submitting an issue.
YOU MAY DELETE THE PREREQUISITES SECTION.
Expected behavior
Please describe the behavior you were expecting
I am trying to mock Named ranges array of excel so i can run some tests on adding and removing custom ranges, but it appears that the mock object is not equipped to handle arrays?
Using Jest and in Angular.
As per the documentation i am mocking the Host object and assigning it to the global.Excel
Then in my service
The line mentioned above produces the following error
Changing the code slightly to instead use context.load(workbook.names, 'items') produces a different error
Also trying workbook.names.load('items') works but items is undefined even though it was clearly defined in the mock object.
All of the ways tested above work when the code is run properly within an office environment and only fail with mocking.
The only workaround that worked was:
Expected behaviour
I would expect any code that runs fine when not under test to work with the mock object as well.
The text was updated successfully, but these errors were encountered: