How to create TypeScript Unit Tests for functions have an Object Set input

Hi I have a function which uses ObjectSet as an input. I’m creating unit tests but it doesn’t work. Below is my function and the unit test code.

    @Function()
    public async testFunction (testObjectSet: ObjectSet<fakeObject>): Promise<ObjectSet<fakeObject>> {
        
        const result = await testObjectSet 
        .groupBy(obj => obj.title.exactValues({maxBuckets: 10})) 
        .max(obj => obj.submittedAt); 

        const newResult = fakeObject.filter(note => 
            note.submittedAt.exactMatch(result.buckets.find(group => note.title.exactMatch(group.key))?.value!)   
        );

        return newResult;
    }
whenObjectSet(Objects.search().fakeObject().all()).thenReturn(stubSet);
        var temp = Objects.search().fakeObject()
        var result =  await (await myFunctions.testFunction(temp))
1 Like

I believe Objects.search() doesn’t work in tests and will just return undefined - do you have to take in an object set or could you pass in a list of objects instead? Something like myObject[]

I could pass an array of objects, then won’t be able to use the ObjectSet related functions.

Hey @Jzzz! There is an emulator feature in development that will allow you to mimic a the behavior of queries within a unit test. This emulator will use the data created in your unit test and most queries will just work like you would expect (there will be some functionality that will still require stubbing such as fuzzy searches). This feature should available in beta later this year or early next year.

Hi, I am curious the status of this emulator feature :slight_smile: I dont see anything about it in the docs yet.

Hey @a2b027479732f76e99ff so there still ongoing work but it’s mostly focused on the new version that will be based on the OSDK. This solution will likely be released publicly in the first half of this year although this has yet to confirmed as there is still some ongoing debate about what testing infrastructure for OSDK backed functions will look like.

In the meantime, if getting access to the current OSS emulator is important for your existing functions codebase, I can reach out through email or you can reach out to your palantir representative.

Is there an update on this emulator, or any other way of creating ObjectSet collections for unit tests?

I want to mock an ObjectSet collection of our custom object type. I’ve made these attempts with the corresponding errors:

// Type 'null' is not assignable to type 'ObjectSet'.
const mockObjects: ObjectSet<CustomObject> = null;

and

// Type 'never[]' is missing the following properties from type 'ObjectSet': searchAround, orderBy, orderByRelevance, all, and 12 more.
const mockObjects: ObjectSet<CustomObject> = [];

and

// Type '() => void' is not assignable to type 
// '<TResult extends FunctionsApi.OntologyObject>(propertySelector: 
//      (object: CustomObject) => SearchAroundObjectSetProvider<TResult>) 
// => ObjectSet<...>'.
const mockObjects: ObjectSet<CustomObject> = {
    searchAround: () => {},
    orderBy: () => {},
    orderByRelevance: () => {},
    all: () => {},
};

We have a function that finds all objects of customProperty “my_type” with a specific id and performs modifications on the items:

@OntologyEditFunction()
public async modifyObject(id: string): Promise<void> {
    const listOfObjects = Objects.search().customObject().filter(
            (anObject) => Filters.and(anObject.id.exactMatch(id),anObject.customProperty.exactMatch('my_type'))
        ).all();
    // Perform modifications on listOfObjects as needed
}

We want to mock the “api / database call” Objects.search().customObject() to return a hardcoded mock object defined in our test

const mockObjects = [
    {
        id: 'test-id-456',
        customProperty: 'my_type',
    }
];

const mockSearch = {
    customObject(): jest.fn().mockReturnValue(mockObjects)
};

Running the test with Jest gives this error, since the id type is ‘string’:

TypeError: anObject.id.exactMatch is not a function
TypeError: anObject.customProperty.exactMatch is not a function

I tried to alleviate this by changing the mock object to have a similar structure as the filter expects:

id: {
        id: 'test-id-456', // not sure if this matches?
        exactMatch: (test) => test === 'test-id-456'
    },
customProperty: {
        customProperty: 'my_type', // not sure if this matches?
        exactMatch: (test) => test === 'my_type'
    },

Running the test with Jest gives this error

TypeError: ontology_api_1.Objects.search(...).customObject(...).filter(...).all is not a function

Overall, I’m hoping for something like an Object Literal:

const mockObjects = [
    {
        id: 'test-id-456',
        customProperty: 'my_type',
    }
];

or a class with getters / setters:

// HashMap in Java:
ObjectSet<CustomObject> customObjects = new ObjectSet<CustomObject>();
customObjects.put({
        id: 'test-id-456',
        customProperty: 'my_type',
    });

Thank you!

Hey! There likely won’t be any emulators released for TypeScript v1 functions given that v2 functions are available now. To stub the search result, you can follow this guide. In your case, it might look something like this:

import { whenObjectSet } from "@foundry/functions-testing-lib";

whenObjectSet(
        Objects.search().customObject().filter(
            (anObject) => Filters.and(anObject.id.exactMatch("<VALUE>"),anObject.customProperty.exactMatch('my_type'))
        ).all()
).thenReturn([myMockObject])

You should do this in your test before calling the function you want to test.

Hi Smith, I appreciate the quick response. It sounds like using v2 is the only path forward?

The issue we face is that our client’s environment doesn’t support v2, so we’re limited to v1. OSDK fails to compile with actions that modify a particular object property. This property has some other known quirks that we’ve had to work around. Typescript v2 doesn’t compile because it runs on OSDK.

Knowing that, is there any path forward for using hard-coded ObjectSets in our unit tests?