public static String getGeneratedResourceString(GeneratedResource generatedResource) throws JsonProcessingException {
        return objectMapper.writeValueAsString(generatedResource);
    }
@Test
    void getGeneratedResourceString() throws JsonProcessingException {
        String fullClassName = "full.class.Name";
        GeneratedResource generatedResource = new GeneratedClassResource(fullClassName);
        String expected = String.format("{\"step-type\":\"class\",\"fullClassName\":\"%s\"}", fullClassName);
        String retrieved = JSONUtils.getGeneratedResourceString(generatedResource);
        assertThat(retrieved).isEqualTo(expected);

        LocalUri modelLocalUriId = new ReflectiveAppRoot("test")
                .get(ComponentFoo.class)
                .get("this", "is", "modelLocalUriId")
                .asLocalUri();
        ModelLocalUriId localUriId = new ModelLocalUriId(modelLocalUriId);

        String target = LocalComponentIdFoo.PREFIX;
        generatedResource = new GeneratedRedirectResource(localUriId, target);
        expected = String.format("{\"step-type\":\"redirect\",\"modelLocalUriId\":%s,\"target\":\"%s\"}",
                                 JSONUtils.getModelLocalUriIdString(localUriId), target);
        retrieved = JSONUtils.getGeneratedResourceString(generatedResource);
        assertThat(retrieved).isEqualTo(expected);

        generatedResource = new GeneratedExecutableResource(localUriId, Collections.singletonList(fullClassName));
        expected = String.format("{\"step-type\":\"executable\",\"modelLocalUriId\":%s,\"fullClassNames\":[\"%s\"]}",
                                 JSONUtils.getModelLocalUriIdString(localUriId), fullClassName);
        retrieved = JSONUtils.getGeneratedResourceString(generatedResource);
        assertThat(retrieved).isEqualTo(expected);
    }