객체 검색과 집계의 테스트 응답
TSv1 테스트의 whenObjectSet은 특정 검색 또는 집계가 반환할 응답을 지정합니다. @foundry/functions-testing-lib에서 가져옵니다. 대체 응답은 함수의 처리 로직을 검사하기 위한 값이며 실제 검색 엔진의 결과를 검증하는 수단은 아닙니다.
테스트 대상 함수
가상의 ObjectType은 String 기본 키 id, 숫자 prop과 property, 정렬 가능한 String label 및 linkField 자기 관계를 갖는다고 가정합니다. 검색 바인딩은 objectType, 탐색 바인딩은 searchAroundLinkField입니다.
src/objectSearchFunctions.ts에 다음 클래스를 작성합니다.
import { Double, Function, UserFacingError } from "@foundry/functions-api";
import { Objects, ObjectSet, ObjectType } from "@foundry/ontology-api";
export class ObjectSearchFunctions {
@Function()
public filterObjectSet(objects: ObjectSet<ObjectType>): ObjectSet<ObjectType> {
return objects.filter(object => object.prop.range().gte(0));
}
@Function()
public async aggregateSum(): Promise<Double> {
const total = await Objects.search().objectType().sum(object => object.property);
if (total === undefined) throw new UserFacingError("집계 합계가 없습니다.");
return total;
}
@Function()
public async sumFirstTen(objects: ObjectSet<ObjectType>): Promise<Double> {
const rows = await objects.orderBy(object => object.label.asc()).takeAsync(10);
let total = 0;
for (const row of rows) {
if (row.property === undefined) throw new UserFacingError("합계에 필요한 값이 없습니다.");
total += row.property;
}
return total;
}
@Function()
public linkedObjects(object: ObjectType): ObjectType[] {
return [...Objects.search().objectType([object]).searchAroundLinkField().all()];
}
}
필터 정의 비교
src/tests/objectSearchFunctions.ts에서 집합을 실제 로드하지 않고 필터 정의를 비교할 수 있습니다.
import { Objects } from "@foundry/ontology-api";
import { whenObjectSet } from "@foundry/functions-testing-lib";
import { ObjectSearchFunctions } from "../objectSearchFunctions";
const functions = new ObjectSearchFunctions();
test("builds the nonnegative filter", () => {
const objects = Objects.search().objectType();
expect(functions.filterObjectSet(objects))
.toEqual(objects.filter(object => object.prop.range().gte(0)));
});
test("returns the aggregation response", async () => {
whenObjectSet(Objects.search().objectType().sum(object => object.property)).thenReturn(55);
await expect(functions.aggregateSum()).resolves.toEqual(55);
});
test("sums the selected ordered rows", async () => {
const objects = Objects.search().objectType();
const employee = Objects.create().objectType("employee-test");
employee.label = "A";
employee.property = 65;
whenObjectSet(objects.orderBy(object => object.label.asc()).takeAsync(10))
.thenReturn([employee]);
await expect(functions.sumFirstTen(objects)).resolves.toEqual(65);
});
집계 응답 55와 로드된 객체의 속성 65는 서로 다른 테스트 입력입니다. 정렬 조건은 orderBy에 실제 속성을 지정하며, 비동기 검증을 await해야 끝까지 실행합니다.
객체 목록으로 만든 집합 구분
검색 생성자에 테스트 객체를 넘길 때는 각 객체에 rid를 설정해야 합니다. 다음 ridA와 ridB는 테스트 라이브러리에서만 쓰는 가상 식별자입니다.
같은 테스트 파일에 추가합니다.
test("distinguishes explicit object sets", () => {
const objectA = Objects.create().objectType("a");
const objectB = Objects.create().objectType("b");
objectA.rid = "ridA";
objectB.rid = "ridB";
whenObjectSet(Objects.search().objectType([objectA]).all()).thenReturn([objectA]);
whenObjectSet(Objects.search().objectType([objectA, objectB]).all()).thenReturn([objectA, objectB]);
expect(Objects.search().objectType([objectA]).all()).toEqual([objectA]);
expect(Objects.search().objectType([objectA, objectB]).all()).toEqual([objectA, objectB]);
});
링크 탐색 응답
단일 객체를 검색 생성자에 넘긴 뒤 Search Around로 탐색하는 검색도 대체할 수 있습니다. 생성자에 전달할 출발 객체에는 rid가 필요합니다.
test("loads the specified link traversal", () => {
const objectA = Objects.create().objectType("a-link");
const objectB = Objects.create().objectType("b-link");
objectA.rid = "ridA-link";
whenObjectSet(Objects.search().objectType([objectA]).searchAroundLinkField().all())
.thenReturn([objectB]);
expect(functions.linkedObjects(objectA)).toEqual([objectB]);
});
객체의 링크 상태를 직접 만들고 함수가 이를 바꾸는지를 확인하려면 편집 검증을 사용합니다.