{"id":20550883,"url":"https://github.com/artodeschini/unit_tests_quarkus_java","last_synced_at":"2026-02-07T13:32:26.565Z","repository":{"id":113860577,"uuid":"476043317","full_name":"artodeschini/unit_tests_quarkus_java","owner":"artodeschini","description":"java java11 maven ","archived":false,"fork":false,"pushed_at":"2022-03-30T20:57:20.000Z","size":8,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-31T10:14:45.546Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/artodeschini.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-30T20:36:55.000Z","updated_at":"2022-03-30T20:36:55.000Z","dependencies_parsed_at":"2023-07-13T18:16:37.312Z","dependency_job_id":null,"html_url":"https://github.com/artodeschini/unit_tests_quarkus_java","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/artodeschini/unit_tests_quarkus_java","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artodeschini%2Funit_tests_quarkus_java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artodeschini%2Funit_tests_quarkus_java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artodeschini%2Funit_tests_quarkus_java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artodeschini%2Funit_tests_quarkus_java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/artodeschini","download_url":"https://codeload.github.com/artodeschini/unit_tests_quarkus_java/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artodeschini%2Funit_tests_quarkus_java/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29195174,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T12:38:28.597Z","status":"ssl_error","status_checked_at":"2026-02-07T12:38:23.888Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T02:27:46.691Z","updated_at":"2026-02-07T13:32:26.549Z","avatar_url":"https://github.com/artodeschini.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Testes unitários com Quarkus\n\n## Requisitos\n\n* Java 8 ou 11 (desejavel 11)\n* Maven 3.6.3 ou \u003e\n* Quarkus\n* JUnit 5\n* Mokito\n* Quarkus\n* Curiosidade com TDD\n\n## TDD\n\nOs testes unitários são muito utilizados no TDD (Test-Driven Development), uma metodologia de desenvolvimento que se baseia nos testes para implementar as funcionalidades (ao invés de fazer o contrário, que é mais comum)\n\nBoas práticas na práticas\n\nQuando falamos em TDD é bom destacar que estamos falando em utilizar o Teste Unitário diretamente como ferramenta de desenvolvimento, portanto algumas práticas citadas aqui são aplicáveis como boas práticas direcionadas ao uso do teste unitário.\n\nPara escrever testes de qualidade, precisamos ter em mente três ideias centrais:\n\n1. Testes precisam ser confiáveis. Seus testes precisam dar a certeza de que eles não possuem bugs\n\n2. Testes precisam ser legíveis. Os testes devem indicar claramente o que está acontecendo à primeira vista. Um teste que não dá pra saber o que está sendo testado não serve para nada.\n\n3. Testes precisam ser sustentáveis Os testes precisam seguir a escalabilidade do software que eles testam. Idealmente os testes devem ser imutáveis, portanto é importante garantir que eles se comportem da forma intencionada conforme o código é escalado.\n\nÉ importante ter sempre esse tripé em mente quando estiver escrevendo testes unitários, especialmente no caso do Desenvolvimento Guiado por Testes.\n\n1 - Apenas escrever código em resposta a um teste falhando\nIsso é a base de trabalhar com Desenvolvimento Guiado por Testes: escrever um teste que falha e fazê-lo ter sucesso com o código de produção, então os seus testes sempre devem ser escritos antes dos métodos de produção. Pode parecer um pouco óbvio, mas é muito comum perder o foco e \"furar\" o TDD quando a implementação é algo muito simples ou que o programador tem certeza que \"não tem como dar errado\". Mas a verdade é que \"furar\" o TDD é uma má prática e acaba deixando o software vulnerável a erros bobos que poderiam ter sido evitados. Isso auxilia a criação de testes confiáveis já que você sempre vai ver seu teste falhar e ter sucesso\n\n2 - Nomeie os seus testes de forma autoexplicativa\nCódigo de testes deve ser mais legível que código de produção, então não há necessidade de nomear os métodos de teste de forma minimalista. Prefira nomear os testes da forma que fique o mais claro possível o que o teste está fazendo, mesmo que o nome fique grande e/ou não siga convenções nominais de métodos.\n\n3 - Rodar os testes diversas vezes\nTeste antes de codificar, após codificar e teste mais uma vez após refatorar o código, não importa o quão pequena for a alteração. Adotando esse tipo de prática, você assegura que seu código não vai quebrar em nenhum momento e passar despercebido.\n\n4 - Teste apenas uma coisa por vez\nExistem ferramentas de Teste Unitário que permitem que os métodos de teste tenham mais de um assert em si, como por exemplo o JUnit. Apesar de ser permitido pela ferramenta, isso é considerado uma má prática porque prejudica a clareza do teste sendo feito, aumenta a chance de ter bugs nos seus testes e torna debugar mais trabalhoso. Teste uma coisa só por vez.\n\n5 - Não ponha lógica nos seus testes (Pelo menos tente)\nTestes não devem conter lógica. Se o seu teste possui um if ou switch é porque você, provavelmente, está testando mais de uma coisa, e aumenta muito a chance de ter bugs no seu código de teste.\n\n6 - Testes existentes devem passar antes de criar um novo teste\nAs vezes é tentador ignorar um teste que falha e partir pra criação do outro. Ou ainda escrever múltiplos testes de uma vez antes de implementar o código de produção. Isso deve ser evitado porque prejudica a clareza dos seus testes. Um dos objetivos do TDD é que a implementação do código de produção deve funcionar como o esperado sempre e quebrar essa regra geralmente se torna adiar o inevitável, já que o programador terá que implementar o código de produção eventualmente.\n\n7 - Faça o teste passar da forma mais simples possível\nA ideia é que quanto mais simples for a implementação mais fácil e melhor será de manter em produção ela será. Isso quer dizer que a maioria das aplicações funcionam melhor quando são mantidas simples ao invés de desnecessariamente complexas.\n\n8 - Não use dependência entre testes\nCada teste deve executar independentemente de outros, portanto, programadores devem ser capazes de executar cada teste individualmente, grupos de teste ou todos os testes de uma vez. Haver dependências entre os testes os tornam mais propícios a bugs com a introdução de novos testes.\n\n9 - Não remova nem altere testes antigos\nEvite ao máximo possível alterar ou remover qualquer teste que já esteja passando. A grande vantagem de utilizar o Teste Unitário, e por consequência o TDD, é a manutenção do código de testes que é executado após cada alteração no código de produção. Alterar ou remover testes que funcionam faz perder totalmente o propósito dos testes que foram construídos.\n\nAs únicas exceções seriam no caso da implementação ser removida ou ter seu propósito alterado.\n\n10 - Tente sempre utilizar o padrao Given (Dado) / When (quando) / Then (entao) \n\nIsso auxilia os demais desenvolvedores a entenderem o teste onde no **Given** (dado) é produzido ou realizado o mock de tudo que você precisa para testar aquele cenário. Ao chamar o método ou a classe **When**, eu **Then** (então) você obtem o seguinte resultado. \n\n```java\n// codigo abastraido\n\n\t\t/** \n  \t\t* If an item is loaded from the repository, the name of that item should \n  \t\t* be transformed into uppercase. */ \n  \t  \t@Test \n\t  \t  \tpublic void shouldReturnItemNameInUpperCase() { \n\t\t  \t// \n\t\t  \t// Given //\n\t\t  \t// fornecido valores\n\t\t  \t// para java 8 \n\t\t  \t// Item mockedItem = new Item(\"it1\", \"Item 1\", \"Este e o primeiro item\", 2000, true); \n\t\t  \t// para java 11\n\t\t  \tvar mockedItem = new Item(\"it1\", \"Item 1\", \"Este e o primeiro item\", 2000, true); \n\t\t  \twhen(itemRepository.findById(\"it1\")).thenReturn(mockedItem); \n\t\t  \n\t\t  \n\t\t  \t// When //\n\t\t  \t// Quando eu executo algo\n\t\t  \t// para java 8\n\t\t  \t// String result = itemService.getItemNameUpperCase(\"it1\"); \n\t\t  \t// para java 11 \n\t\t  \tvar result = itemService.getItemNameUpperCase(\"it1\"); \n\t\t  \n\t\t  \t// Then //\n\t\t  \t// então eu obtenho asassertivas\n\t\t\n\t\t  \tverify(itemRepository, times(1)).findById(\"it1\"); assertThat(result, is(\"ITEM 1\")); \n\t \t}\n```\n\n## Maven dependencias\n\n```xml\n\u003c!-- omitido o começo do pom.xml --\u003e\n\u003cdependency\u003e\n\t\u003cgroupId\u003eio.quarkus\u003c/groupId\u003e\n\t\u003cartifactId\u003equarkus-junit5\u003c/artifactId\u003e\n\t\u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n\t\u003cgroupId\u003eio.quarkus\u003c/groupId\u003e\n\t\u003cartifactId\u003equarkus-junit5-internal\u003c/artifactId\u003e\n\t\u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.quarkus\u003c/groupId\u003e\n    \u003cartifactId\u003equarkus-junit5-mockito\u003c/artifactId\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n\u003c!-- opctional mas deixa o seu código mais legivel --\u003e\n\u003cdependency\u003e\n\t\u003cgroupId\u003eio.rest-assured\u003c/groupId\u003e\n\t\u003cartifactId\u003erest-assured\u003c/artifactId\u003e\n\t\u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n\u003c!-- em caso de teste com repositorio utilize o banco de dados h2 --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.quarkus\u003c/groupId\u003e\n    \u003cartifactId\u003equarkus-jdbc-h2\u003c/artifactId\u003e\n\u003c/dependency\u003e\n\u003c!-- continua --\u003e\n```\n\n## import static\n\nUtilize import static pois eles facilitam a leitura dos testes.\n\nExemplo:\n\n```java\n// importes\nimport static io.restassured.RestAssured.given;\nimport static org.hamcrest.CoreMatchers.is;\n\nimport static org.junit.jupiter.api.Assertions.*;\nimport static org.mockito.Mockito.*;\n\n\n\t//exemplo de códigos\t\n\n \t// implementacao omitida\n\t// use dessa forma \n\twhen(mock.findAllUsuariosByDataSource()).thenReturn(usuarios);\n\t// ao inves de usar com Mockito.*\n\t//Mockito.when(mock.findAllUsuariosByDataSource()).thenReturn(usuarios);\n\n\t// use dessa forma\n\tverify(itemRepository, times(1)).findById(\"it1\"); assertThat(result, is(\"ITEM 1\"));\n\t// ao inves de usar com Mockito.*\n\t//Mockito.verify(itemRepository, times(1)).findById(\"it1\"); assertThat(result, is(\"ITEM 1\"));\n\n\t// use dessa forma\n\tgiven().when().get(\"/config/query\").then().statusCode(200).body(is(H2Profile.QUERY));\n\t// ao inves de usar\n\t//RestAssured.given()..when().get(\"/config/query\").then().statusCode(200).body(CoreMatchers.is(H2Profile.QUERY));\n\n```\n\n## Teste unitario sobrescrevendo o profile com Quarkus\n\nSe voce desejar sobrescrever alguma propriedade do application.properties para algum test em especifico pode utilizar esta forma\n\n```java\nimport org.eclipse.microprofile.config.inject.ConfigProperty;\n\nimport javax.inject.Inject;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.MediaType;\nimport javax.ws.rs.core.Response;\nimport java.util.logging.Logger;\n\n@Path(\"/config\")\npublic class SgnResource {\n\n    private static Logger LOGGER = Logger.getLogger(SgnResource.class.getName());\n\n    @ConfigProperty(name = \"query.pix\")\n    private String query;\n\n   \n    @GET\n    @Path(\"/query\")\n    @Produces(MediaType.TEXT_PLAIN)\n    public Response getQuery() {\n        return Response.ok(query).build();\n    }\n}\n```\n\nCrie um profile de test\n\n```java\nimport io.quarkus.test.junit.QuarkusTestProfile;\n\nimport java.util.Map;\n\npublic class H2Profile implements QuarkusTestProfile {\n\n    public static final String QUERY = \"uma query diferente\";\n\n    @Override\n    public Map\u003cString, String\u003e getConfigOverrides() {\n        return Map.of(\n                \"quarkus.datasource.url\", \"jdbc:h2:tcp://localhost/mem:test\",\n                \"quarkus.datasource.driver\", \"org.h2.Driver\",\n                \"quarkus.hibernate-orm.database.generation\", \"drop-and-create\",\n                \"quarkus.hibernate-orm.log.sql\", \"true\",\n                \"query.pix\", QUERY\n        );\n    }\n\n    @Override\n    public String getConfigProfile() {\n        return \"h2\";\n    }\n```\n\nTeste\n\n```java\nimport io.quarkus.test.junit.QuarkusTest;\nimport io.quarkus.test.junit.TestProfile;\nimport org.junit.jupiter.api.Test;\n\nimport javax.inject.Inject;\n\nimport java.text.MessageFormat;\n\nimport static io.restassured.RestAssured.given;\nimport static org.hamcrest.CoreMatchers.is;\n\n@QuarkusTest\n@TestProfile(H2Profile.class) //injeta o profile de teste customizado\nclass SgnResourceTest {\n\n    @Inject\n    SgnResource api;\n\n    @Test\n    public void testLoadQuery() {\n        given()\n                .when().get(\"/config/query\")\n                .then()\n                .statusCode(200)\n                .body(is(H2Profile.QUERY));\n    }\n}\n```\n\n\n## Teste unitario com JUnit5 e Mockito utilizando Quarkus e injeção de depedencias\n\nClasse de repositorio\n\n```java\n@ApplicationScoped\npublic class UsuarioRepository implements PanacheRepository\u003cUsuario\u003e {\n    @Inject\n    private AgroalDataSource dataSource;\n\n    public List\u003cUsuario\u003e findAllUsuariosByDataSource() {\n        List\u003cUsuario\u003e dados = new ArrayList\u003c\u003e();\n        try (PreparedStatement preparedStatement = dataSource.getConnection().prepareStatement(\"SELECT id, nome, sobrenome, idade from Usuario \")) {\n            ResultSet rs = preparedStatement.executeQuery();\n            Usuario usuario;\n            while (rs.next()) {\n                usuario = new Usuario();\n                usuario.setId(rs.getLong(\"id\"));\n                usuario.setNome(rs.getString(\"nome\"));\n                usuario.setSobrenome(rs.getString(\"sobrenome\"));\n                usuario.setIdade(rs.getInt(\"idade\"));\n\n                dados.add(usuario);\n            }\n        } catch (SQLException e) {\n            LOGGER.severe(e.getMessage());\n        }\n        return dados;\n    }\n\n\n}\n```\n\nClasse de servico\n\n```java\n@ApplicationScoped\npublic class SgnService {\n\n    @Inject\n    private UsuarioRepository repository;\n\n    private static final Logger LOGGER = Logger.getLogger(SgnService.class.getName());\n\n    public List\u003cUsuario\u003e findAllUsuariosByDataSource() {\n        return repository.findAllUsuariosByDataSource();\n    }\n}\n```\n\nClasse de teste\n\n```java\n@QuarkusTest\npublic class SgnServiceTest {\n\n    @Inject\n    SgnService service;\n\n    @Test\n    public void testFindAllUsuariosByDataSource() {\n\t\t//given\n        UsuarioRepository mock = Mockito.mock(UsuarioRepository.class);\n        List\u003cUsuario\u003e usuarios = new ArrayList\u003c\u003e();\n        usuarios.add(new Usuario());\n        \n\t\t// mock com mockito\n\t\twhen(mock.findAllUsuariosByDataSource()).thenReturn(usuarios);\n\n        // faz a substituição da injeção de dependencia \n        QuarkusMock.installMockForType(mock, UsuarioRepository.class);\n\t\t \n\t\t// when \n\t\tint size = service.findAllUsuariosByDataSource().size();\n\n\t\t// then\n        assertEquals(1, size);\n    }\n}\n```\n\n[link externo referencia quarkus com mockito](https://quarkus.io/blog/mocking/)\n\n\n## Utilização de override de metodos anonimos para fugir de implementações com metodos static\n\n- Alguns metodos static são difices de testar, mas podem ser contornados por um override de metodo de classe que o invocar no seu teste.\n- Outra solução que você pode buscar é a utilização do mockito-inline para fugir do PowerMockito e testar metodos static\n\n```java\n\tpublic class OutraClasseDeNegocio {\n\n\t// este metdo ficará coberto só o da integração 'enviaMsgParaMQSViaSgnMensageria' não ficará\n\tpublic boolean hasMensagemRetornoAsString() {\n\t\tString msg this.enviaMsgParaMQSViaSgnMensageria();\n\n\t\treturn msg.contains(\"RETORNO\");\n\t}\n\n\t// tente isolar a chamada dentro de um metodo seu\n\t// você não terá ele na sua coverage, mas desviará dele não fazendo a sua chamada\n\t// mantenha ele public ou protected para que possa ser acessivel no mesmo packege pelo teste\n\tpublic String enviaMsgParaMQSViaSgnMensageria(String fila, String mensagem) {\n\t\treturn Grpc.publicarMensagemGrpc(fila, mensagem);\n\t}\n}\n```\n\nClasse de teste \n\n```java\n\nclass OutraClasseDeNegocioTest {\n\n\tprivate OutraClasseDeNegocio negocio;\n\n\t@Test\n\tpublic void testFazAlgoComMsg() {\n\t\t// given\n\t\t// importante faça o override do metodo e de o retorno adequado no seu objeto \n\t\tnegocio = new OutraClasseDeNegocio() {\n\t\t\t@Override\n\t\t\tpublic String enviaMsgParaMQSViaSgnMensageria(String fila, String mensagem) {\n\t\t\t\treturn \"RETORNO_MSQ\"; // coloque o retorno que você aguarda da chamada no caminho feliz\n\t\t\t}\n\t\t}\n\n\t\t// When / Then\n\t\t//desta forma você consegue isolar e testar o seu negocio, sem se preocupar com a integracao com o Grpc\n\t\tassertTrue(negocio.hasMensagemRetornoAsString());\n\t}\n}\n```\n\n## Criando um teste que utiliza a chamada de uma classe que implementa o padrão Singleton compativel com java 11 sem PowerMockito\n\n- Não recomendo a utilização deste padrão de projeto, porém como há varios subprojetos que utilizam estou colocando como resolver isso.\n\n\nParte do corpo da classe ConfiguradorService antes da alteração\n\n```java\npublic class ConfiguradorService {\n\n\tprivate static final Logger LOGGER = Logger.getLogger(ConfiguradorService.class.getName());\n\n\tprivate static ConfiguradorService instance;\n\n\tpublic ConfiguradorService() {\n\t\tsuper();\n\t}\n\n\tpublic static synchronized ConfiguradorService getInstance() {\n\t\tif (instance == null) {\n\t\t\tinstance = new ConfiguradorService();\n\t\t}\n\t\treturn instance;\n\t}\n\n    /// ..... código continua\n```\n\nA solução foi criar uma interface que continha todas as assinaturas dos metodos da classe ConfiguradorService.\n\nCódigo da interface\n\n```java\npackage org.todeschini.service;\n\nimport java.util.List;\n\nimport org.todeschini.configuracao.utils.componente.ComponenteConfiguradorBase;\nimport org.todeschini.configuracao.utils.enums.TipoServicoEnum;\n\npublic interface InterfaceConfigurador {\n\n\tpublic \u003cT extends ComponenteConfiguradorBase\u003e T obter(TipoServicoEnum tipoServico);\n\tpublic \u003cT extends ComponenteConfiguradorBase\u003e List\u003cT\u003e obterLista(TipoServicoEnum tipoServico);\n\tpublic String obterFinalidade(String finalidade);\n\tpublic String obterFuncao(String nomeFuncao);\n\tpublic String obterConfiguracaoIndicioFraudePorTipo(String tipoIndicioFraude);\n\tpublic String obterConfiguracaoIndicioFraudePorId(String id);\n\tpublic String obterBloqueio();\n\tpublic String obterConfiguracao(String tipo, String dado);\n\tpublic String obterTriagem(String tipo);\n}\n```\n\nVolte na classe ConfiguradorService e faça com que ela implemente a nova interface\n\n```java\n                                 // adicionando isso a classe original \npublic class ConfiguradorService implements InterfaceConfigurador {\n    // codigo abstraido...\n```\n\n* Note que dessa forma não foi mechido em nada que afete a classe ConfiguradorService mantendo-a como toda sua coesão que o padrão Singleton lhe oferece.\n\nCrie uma camada para abstrair a integração\n\n* nota utilize os metodos get e set com o modificador synchronized especialmente devido aos testes quando houver concorrencia\n\n```java\npackage org.todeschini.integracao;\n\nimport org.todeschini.service.ConfiguradorService;\nimport org.todeschini.service.InterfaceConfigurador;\n\npublic class Integrador {\n\t\n\tprivate static volatile Integrador instance;\n    private InterfaceConfigurador configurador;\n\t\n\tpublic static synchronized Integrador getInstance() {\n\t\tif (instance == null) {\n\t\t\tinstance = new Integrador();\n\t\t}\n\t\treturn instance;\n\t}\n\t\n\tpublic synchronized InterfaceConfigurador getConfigurador() {\n\t\tif (configurador == null) {\n\t\t\tsetConfigurador(ConfiguradorService.getInstance());\n\t\t}\n\t\treturn configurador;\n\t}\n\n\tpublic synchronized void setConfigurador(InterfaceConfigurador configurador) {\n\t\tthis.configurador = configurador;\n\t}\n}\n\n```\n\nEm todas as classe que você gostaria de chamar o Configurador agora utilize da seguinte forma\n\n```java\n    String finalidade = Integrador.getInstance().getConfigurador().obterFinalidade(\"teste\");\n```\n\nJá para os testes você pode injetar na classe uma outra implementação de InterfaceConfigurador que seja Fake  \n\nComo a configuração é algo muito especifico de cada projeto mantenha o Fake no no seu projeto no diretorio de testes\n\n```java\npackage org.todeschini.integracao;\n\nimport java.util.List;\n\nimport org.todeschini.configuracao.utils.componente.ComponenteConfiguradorBase;\nimport org.todeschini.configuracao.utils.componente.ComponenteConfiguradorMapeamentoEntrada;\nimport org.todeschini.configuracao.utils.componente.ComponenteConfiguradorMapeamentoSaida;\nimport org.todeschini.configuracao.utils.componente.ComponenteConfiguradorPesquisaMainframe;\nimport org.todeschini.configuracao.utils.enums.TipoServicoEnum;\nimport org.todeschini.service.InterfaceConfigurador;\n\npublic class ConfiguradorFake implements InterfaceConfigurador {\n\n    // JDBC driver name and database URL\n\tpublic static final String H2_URL = \"jdbc:h2:mem:sample;\";\n\tpublic static final String JDBC_DRIVER = \"org.h2.Driver\";\n\n\t// Database credentials\n\tpublic static final String USER = \"sa\";\n\tpublic static final String PASS = \"sa\";\n\n\tpublic static final String NOME_FINALIDADE = \"TESTE\";\n\n\tpublic static final String FINALIDADE = \"{\\\"finalidade\\\" : \\\"\" + NOME_FINALIDADE + \"\\\",\"\n\t\t\t+ \"\\\"tipo\\\" : \\\"BANCO_DADOS\\\",\\\"dados\\\" : {\\\"tipoConexao\\\" : \\\"H@\\\", \\\"driver\\\" : \\\"\" + JDBC_DRIVER + \"\\\"\"\n\t\t\t+ \",\\\"url\\\" : \\\"\" + H2_URL + \"\\\",\\\"usuario\\\" : \\\"\" + USER + \"\\\",\\\"senha\\\" : \\\"\" + PASS\n\t\t\t+ \"\\\"},\\\"ativo\\\" : true}\";\n\t\n\t// crie os componentes que você deseje utilizar e faça o emcapsulamento dele\n\tprivate ComponenteConfiguradorMapeamentoEntrada mapaEntrada = null;\n\tprivate ComponenteConfiguradorPesquisaMainframe mapaPesquisa = null;;\n\tprivate ComponenteConfiguradorMapeamentoSaida mapaSaida = null;\n\tprivate String bloqueio = null;\n\t\n\t@SuppressWarnings(\"unchecked\")\n\t@Override\n\tpublic \u003cT extends ComponenteConfiguradorBase\u003e T obter(TipoServicoEnum tipoServico) {\n\t\t//adicione todos os tipos de voce desejar, mas lembre-se de criar um atributo e encapsular para faciliar o envio da configuracao\n\t\tif (tipoServico.name().equalsIgnoreCase(TipoServicoEnum.MAPEAMENTO_ENTRADA.name())) {\n\t\t\treturn (T) mapaEntrada;\n\t\t} else if (tipoServico.name().equalsIgnoreCase(TipoServicoEnum.MAPEAMENTO_SAIDA.name())) {\n\t\t\treturn (T) mapaSaida;\n\t\t} else if (tipoServico.name().equalsIgnoreCase(TipoServicoEnum.PESQUISA_MAINFRAME.name())) {\n\t\t\treturn (T) mapaPesquisa;\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic String obterFinalidade(String finalidade) {\n\t\treturn FINALIDADE;\n\t}\n\n\t//metodos omiticos sem implementação consideravel\n\n\t// encapsulamento dos Configuracoes\n\tpublic void setMapaEntrada(ComponenteConfiguradorMapeamentoEntrada mapaEntrada) {\n\t\tthis.mapaEntrada = mapaEntrada;\n\t}\n\n\tpublic void setMapaPesquisa(ComponenteConfiguradorPesquisaMainframe mapaPesquisa) {\n\t\tthis.mapaPesquisa = mapaPesquisa;\n\t}\n\n\tpublic void setMapaSaida(ComponenteConfiguradorMapeamentoSaida mapaSaida) {\n\t\tthis.mapaSaida = mapaSaida;\n\t}\n\n\tpublic void setBloqueio(String bloqueio) {\n\t\tthis.bloqueio = bloqueio;\n\t}\n}\n\n```\n\nTeste da classe utilitaria Integrador como exemplo de uso do configurador\n\n```java\npackage org.todeschini.integracao;\n\nimport static org.junit.jupiter.api.Assertions.assertNotSame;\nimport static org.junit.jupiter.api.Assertions.assertSame;\n\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.MethodOrderer;\nimport org.junit.jupiter.api.Order;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.TestMethodOrder;\n\nimport org.todeschini.integracao.fake.ConfiguradorFake;\nimport org.todeschini.service.ConfiguradorService;\n\n@TestMethodOrder(MethodOrderer.OrderAnnotation.class)\npublic class IntegradorTest {\n\n\t@Test\n\t@Order(1)\n\tpublic void isSame() {\n\t\t// given / when\n\t\tvar i1 = Integrador.getInstance();\n\t\tvar i2 = Integrador.getInstance();\n\n\t\t// then \n\t\t//vai obter dois objetos de Integrador que serão: \n\t\t//a mesma instancias de Integrador \n\t\tassertSame(i1, i2);\n\t}\n\n\t@Test\n\t@Order(2)\n\tpublic void getConfiguradorServiceAsInterfaceConfigurador() {\n\t\t// given / when\n\t\tvar service = ConfiguradorService.getInstance();\n\t\tvar configurador = Integrador.getInstance().getConfigurador();\n\t\t\n\t\t// then \n\t\t// vai demostra que as duas instancias obtidas\n\t\t// sao de ConfiguradorService sao a mesma\n\t\tassertSame(service, configurador);\n\t}\n\t\n\t@Test\n\t@Order(3)\n\tpublic void changeConfiguradorBySetConfigurador() {\n\t\t/* given */\n\n\t\tvar service = ConfiguradorService.getInstance();\n\t\tvar fake = new ConfiguradorFake();\n\t\t\n\t\tIntegrador.getInstance().setConfigurador(fake);\n\t\t\n\t\t/* when / then */\n\n\t\t// vai demostrar que se alterar a o valor da instancia de Integrador não será\n\t\t// uma insntancia real de ConfiguradorService \n\t\t// e sim uma implementação da interface InterfaceConfigurador\n\t\tassertNotSame(service, Integrador.getInstance().getConfigurador());\n\t}\n\n\t// Nota importante !!!!! \n\t// lembre-se de utilizar a reflexao e remover do atributo instance\n\t// o valor do fake After/ Before cada teste\n\t@AfterEach\n\tpublic void tearDown() {\n\t\ttry {\n\t\t\tField i = Integrador.class.getDeclaredField(\"instance\");\n\t\t\ti.setAccessible(true);\n\t\t\ti.set(null, null);\n\n\t\t} catch (Exception e) {\n//\t\t\te.printStackTrace();\n\t\t\tfail(e.getMessage());\n\t\t}\n\t}\n}\n```\n\nExemplo de utilização em classes de negocios ...  \n\nClasse de Negocio \n\n```java \npackage org.todeschini.servico;\n\nimport org.todeschini.integracao.Integrador;\n\nimport org.todeschini.configuracao.utils.componente.ComponenteConfiguradorMapeamentoEntrada;\n\npublic class ClasseDeNegocio {\n\n\tprivate ComponenteConfiguradorMapeamentoEntrada entrada;\n\n\tpublic ClasseDeNegocio() {\n\t\tthis.entrada = Integrador.getInstance().getConfigurador().obter(TipoServicoEnum.MAPEAMENTO_ENTRADA);\n\t}\n\t\n\tpublic ComponenteConfiguradorMapeamentoEntrada getEntrada() {\n\t\treturn entrada;\n\t}\n}\n```\n\nTeste da classe de Negocio\n\n\n```java\npackage org.todeschini.servico;\n\npublic class ClasseDeNegocioTest {\n\nimport org.todeschini.integracao.ConfiguradorFake;\nimport org.todeschini.modelo.Propriedade;\n\nimport org.todeschini.configuracao.utils.componente.ComponenteConfiguradorMapeamentoEntrada;\n\n\t@BeforeEach\n\tpublic void setUp() {\n\t\tthis.tearDown();\n\t\tconfigurador = new ConfiguradorFake();\n\t\t//injeta o seu fake no integrador\n\t\tIntegrador.getInstance().setConfigurador(configurador);\n\t}\n\n\t// importante !!!!!\n\t// lembre-se de utilizar a reflexao \n\t// e remover do atributo instance o valor do fake After/Before cada teste\n\t@AfterEach\n\tpublic void tearDown() {\n\t\ttry {\n\t\t\tField i = Integrador.class.getDeclaredField(\"instance\");\n\t\t\ti.setAccessible(true);\n\t\t\ti.set(null, null);\n\n\t\t} catch (Exception e) {\n//\t\t\te.printStackTrace();\n\t\t\tfail(e.getMessage());\n\t\t}\n\t}\n\n\t@Test\n\tpublic void testMeuNegocioComComponenteConfiguradorMapeamentoEntrada() {\n\t\t/* Given */\n\n\t\t//para java 8\n\t\t//ComponenteConfiguradorMapeamentoEntrada entrada = new ComponenteConfiguradorMapeamentoEntrada();\n\t\t//se java 11\n\t\tvar entrada = new ComponenteConfiguradorMapeamentoEntrada();\n\t\tentrada.setCampos(new ArrayList\u003cPropriedade\u003e());\n\t\t\n\t\t// se java 11\n\t\tvar p1 = new Propriedade();\n\t\t// se java 8\n\t\t// Propriedade p1 = new Propriedade();\n\t\tp1.setId(1);\n\t\tp1.setNome(\"minhaPropriedade\");\n\t\tp1.setFixo(true);\n\t\tp1.setTipo(\"Numerico\");\n\t\tp1.setValor(\"1\")\n\n\t\tentrada.getCampos().add(p1);\n\n\t\t//injeta no mapemaneto de entrada no seu configurador\n\t\tconfigurador.setMapaEntrada(entrada);\n\n\t\t// ... chamada da sua classe de negocio com o fake\n\t\t// neste caso o construtor de ClasseDeNegocio faz a chamada para o Integrador e o Configurador\n\t\t\n\t\t/* When */\n\t\t// java 8\n\t\t// ClasseDeNegocio negocio = new ClasseDeNegocio();\n\t\t// java 11\n\t\tvar negocio = new ClasseDeNegocio();\n\n\n\t\t// then \n\t\t// validacoes com assertEquals etc ...\n\t\tassertNotNull(negocio.getEntrada());\n\t\tassertNotNull(negocio.getEntrada().getCampos());\n\t\tassertTrue(negocio.getEntrada().getCampos().size() \u003e 0);\n\n\t\t//se java 8\n\t\t//Propriedade prop = negocio.getEntrada().getCampos().get(0);\n\t\t// se java 11\n\t\tvar prop = negocio.getEntrada().getCampos().get(0);\n\t\t\n\t\tassertEquals(1, prop.getId());\n\t\tassertEquals(\"minhaPropriedade\", prop.getNome());\n\t\tassertTrue(prop.getFixo());\n\t\tassertEquals(\"Numerico\", prop.getTipo());\n\t\tassertEquals(1, Integer.parseInt(prop.getValor()));\n\t}\n}\n\n```\n\n## Teste unisários sem concorrencia\n\nSe não quiser concorrencia nos seus testes, cole isso no seu pom.xml na configuração para maven-surefire-plugin \n\n```xml\n\u003c!-- inicio abstraido --\u003e\n\n\u003cproperties\u003e\n\t\u003ccompiler-plugin.version\u003e3.8.1\u003c/compiler-plugin.version\u003e\n\t\u003cmaven.compiler.parameters\u003etrue\u003c/maven.compiler.parameters\u003e\n\t\u003cmaven.compiler.source\u003e11\u003c/maven.compiler.source\u003e\n\t\u003cmaven.compiler.target\u003e11\u003c/maven.compiler.target\u003e\n\t\u003cproject.build.sourceEncoding\u003eUTF-8\u003c/project.build.sourceEncoding\u003e\n\t\u003cproject.reporting.outputEncoding\u003eUTF-8\n\t\u003c/project.reporting.outputEncoding\u003e\n\t\u003csurefire-plugin.version\u003e2.22.1\u003c/surefire-plugin.version\u003e\n\t\u003cjacoco.version\u003e0.8.4\u003c/jacoco.version\u003e\n\t\u003cdbiq.skip\u003etrue\u003c/dbiq.skip\u003e\n\u003c/properties\u003e\n\n\u003c!--  abstraido --\u003e\n\n\u003cbuild\u003e\n\t\u003cplugins\u003e\n\t\t\u003cplugin\u003e\n\t\t\t\u003cartifactId\u003emaven-compiler-plugin\u003c/artifactId\u003e\n\t\t\t\u003cversion\u003e${compiler-plugin.version}\u003c/version\u003e\n\t\t\t\u003cconfiguration\u003e\n\t\t\t\t\u003cuseIncrementalCompilation\u003efalse\u003c/useIncrementalCompilation\u003e\n\t\t\t\t\u003c!-- configura se o codigo é java 11--\u003e\n\t\t\t\t\u003csource\u003e11\u003c/source\u003e\n\t\t\t\t\u003ctarget\u003e11\u003c/target\u003e\n\t\t\t\u003c/configuration\u003e\n\t\t\u003c/plugin\u003e\n\t\t\u003cplugin\u003e\n\t\t\t\u003cartifactId\u003emaven-surefire-plugin\u003c/artifactId\u003e\n\t\t\t\u003cversion\u003e${surefire-plugin.version}\u003c/version\u003e\n\t\t\t\u003cconfiguration\u003e\n\t\t\t\t\u003cprintSummary\u003etrue\u003c/printSummary\u003e\n\t\t\t\t\u003c!-- no parallelos execute nos teste unitatios uma thread de cada vez--\u003e\n\t\t\t\t\u003cthreadCount\u003e1\u003c/threadCount\u003e\n\t\t\t\t\u003cuseUnlimitedThreads\u003efalse\u003c/useUnlimitedThreads\u003e\n\t\t\t\t\u003cperCoreThreadCount\u003efalse\u003c/perCoreThreadCount\u003e\n\t\t\t\t\u003cthreadCountSuites\u003e1\u003c/threadCountSuites\u003e\n\t\t\t\t\u003cthreadCountClasses\u003e1\u003c/threadCountClasses\u003e\n\t\t\t\t\u003cthreadCountMethods\u003e1\u003c/threadCountMethods\u003e\n\t\t\t\u003c/configuration\u003e\n\t\t\t\u003cexecutions\u003e\n\t\t\t\t\u003cexecution\u003e\n\t\t\t\t\t\u003cid\u003etests\u003c/id\u003e\n\t\t\t\t\t\u003cphase\u003etest\u003c/phase\u003e\n\t\t\t\t\t\u003cgoals\u003e\n\t\t\t\t\t\t\u003cgoal\u003etest\u003c/goal\u003e\n\t\t\t\t\t\u003c/goals\u003e\n\t\t\t\t\u003c/execution\u003e\n\t\t\t\u003c/executions\u003e\n\t\t\u003c/plugin\u003e\n\t\t\u003c!-- abstaido a utilizacao do jacoco --\u003e\n\t\u003c/plugins\u003e\n\u003c/build\u003e\n\u003c!-- abstraido restante do pom --\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartodeschini%2Funit_tests_quarkus_java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fartodeschini%2Funit_tests_quarkus_java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartodeschini%2Funit_tests_quarkus_java/lists"}