### Question:
ReplaceRootStage implements AggregationStage { Document replaceRoot(Document document) { Object evaluatedNewRoot = Expression.evaluateDocument(newRoot, document); if (!(evaluatedNewRoot instanceof Document)) { throw new MongoServerError(40228, "'newRoot' expression must evaluate to an object, but resulting value was: " + Json.toJsonValue(evaluatedNewRoot, true, "{", "}") + ". Type of resulting value: '" + describeType(evaluatedNewRoot) + "'. Input document: " + document.toString(true)); } return (Document) evaluatedNewRoot; } ReplaceRootStage(Document document); @Override Stream<Document> apply(Stream<Document> stream);  }### Answer:
@Test void testReplaceRoot() throws Exception { assertThat(replaceRoot(json("newRoot: '$a'"), json("a: { b: { c: 1 } }"))).isEqualTo(json("b: { c: 1 }")); assertThat(replaceRoot(json("newRoot: '$a.b'"), json("a: { b: { c: 1 } }"))).isEqualTo(json("c: 1")); assertThat(replaceRoot(json("newRoot: { x: '$a.b' }"), json("a: { b: { c: 1 } }"))).isEqualTo(json("x: { c: 1 }")); }
@Test void testIllegalReplaceRoot() throws Exception { assertThatExceptionOfType(MongoServerError.class) .isThrownBy(() -> new ReplaceRootStage(json(""))) .withMessage("[Error 40231] no newRoot specified for the $replaceRoot stage"); assertThatExceptionOfType(MongoServerError.class) .isThrownBy(() -> new ReplaceRootStage(json("newRoot: 1")).replaceRoot(json("a: { b: {} }"))) .withMessage("[Error 40228] 'newRoot' expression must evaluate to an object, but resulting value was: 1. Type of resulting value: 'int'. Input document: {a: {b: {}}}"); assertThatExceptionOfType(MongoServerError.class) .isThrownBy(() -> new ReplaceRootStage(json("newRoot: 'x'")).replaceRoot(json("a: { b: {} }"))) .withMessage("[Error 40228] 'newRoot' expression must evaluate to an object, but resulting value was: \"x\". Type of resulting value: 'string'. Input document: {a: {b: {}}}"); assertThatExceptionOfType(MongoServerError.class) .isThrownBy(() -> new ReplaceRootStage(json("newRoot: '$c'")).replaceRoot(json("a: { b: {} }"))) .withMessage("[Error 40228] 'newRoot' expression must evaluate to an object, but resulting value was: null. Type of resulting value: 'missing'. Input document: {a: {b: {}}}"); assertThatExceptionOfType(MongoServerError.class) .isThrownBy(() -> new ReplaceRootStage(json("newRoot: '$a.c'")).replaceRoot(json("a: { b: {} }"))) .withMessage("[Error 40228] 'newRoot' expression must evaluate to an object, but resulting value was: null. Type of resulting value: 'missing'. Input document: {a: {b: {}}}"); }