<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mairon Costa</title>
    <description>The latest articles on DEV Community by Mairon Costa (@maironmscosta).</description>
    <link>https://dev.to/maironmscosta</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F297563%2Fcfe09b05-bcec-427a-83d7-429f97adc325.jpg</url>
      <title>DEV Community: Mairon Costa</title>
      <link>https://dev.to/maironmscosta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maironmscosta"/>
    <language>en</language>
    <item>
      <title>Testes de Integração no Spring Boot: H2 vs @MockBean com exemplos reais</title>
      <dc:creator>Mairon Costa</dc:creator>
      <pubDate>Wed, 23 Apr 2025 19:26:21 +0000</pubDate>
      <link>https://dev.to/maironmscosta/testes-de-integracao-no-spring-boot-h2-vs-mockbean-com-exemplos-reais-1e6k</link>
      <guid>https://dev.to/maironmscosta/testes-de-integracao-no-spring-boot-h2-vs-mockbean-com-exemplos-reais-1e6k</guid>
      <description>&lt;h2&gt;
  
  
  1. Introdução
&lt;/h2&gt;

&lt;p&gt;Se você chegou até aqui, provavelmente quer entender como fazer testes de integração com Spring Boot, usando &lt;strong&gt;@MockBean&lt;/strong&gt; ou um banco de dados em memória como o &lt;strong&gt;H2&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A diferença entre essas abordagens é simples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Com &lt;strong&gt;@MockBean&lt;/strong&gt;, você simula componentes específicos, retornando valores pré-definidos.&lt;/li&gt;
&lt;li&gt;Com &lt;strong&gt;H2&lt;/strong&gt;, você executa os testes em um banco em memória que simula o comportamento do banco real.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Antes de seguir, é importante entender duas anotações do Spring Boot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@WebMvcTest&lt;/code&gt;: ideal para &lt;strong&gt;testes unitários de controllers&lt;/strong&gt;, sem carregar todo o contexto da aplicação.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@SpringBootTest&lt;/code&gt;: carrega o &lt;strong&gt;contexto completo&lt;/strong&gt; da aplicação, sendo o que usaremos aqui.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Observações importantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o projeto evita o uso de &lt;code&gt;@Service&lt;/code&gt;, &lt;code&gt;@Repository&lt;/code&gt; e &lt;code&gt;@Autowired&lt;/code&gt; , a injeção de dependência é feita de forma manual;&lt;/li&gt;
&lt;li&gt;há links no fim do artigo explicando os motivos para evitar as notações citadas e sobre os tipos de testes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Descubra como escrever testes de integração eficazes com Spring Boot usando duas abordagens poderosas: banco de dados em memória com &lt;strong&gt;H2&lt;/strong&gt; e simulações com &lt;code&gt;@MockBean&lt;/code&gt;. Nesta postagem, será mostrado como configurar cada cenário com exemplos reais, boas práticas e dicas práticas para evitar armadilhas comuns. Testar nunca foi tão direto ao ponto.&lt;/p&gt;

&lt;p&gt;Então, vamos lá!?&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Visão Geral do Projeto
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1. Dependências do Maven (&lt;code&gt;pom.xml&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;O &lt;code&gt;pom.xml&lt;/code&gt; está configurado com dependências para Spring Boot, JPA, PostgreSQL, H2, Lombok e bibliotecas de teste.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0"&lt;/span&gt; &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
    &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;modelVersion&amp;gt;&lt;/span&gt;4.0.0&lt;span class="nt"&gt;&amp;lt;/modelVersion&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;parent&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-parent&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.4.4&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;relativePath/&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- lookup parent from repository --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/parent&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.javawebtest&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;java-web-test&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;0.0.1-SNAPSHOT&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;java-web-test&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;Project to test anything about java web&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;java.version&amp;gt;&lt;/span&gt;17&lt;span class="nt"&gt;&amp;lt;/java.version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-data-jdbc&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-data-jpa&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-web&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-devtools&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;optional&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/optional&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-docker-compose&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;optional&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/optional&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.h2database&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;h2&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.projectlombok&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;lombok&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;optional&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/optional&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-test&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.projectreactor&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;reactor-test&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.postgresql&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;postgresql&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-compiler-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;annotationProcessorPaths&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;path&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.projectlombok&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;lombok&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/path&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/annotationProcessorPaths&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;excludes&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;exclude&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.projectlombok&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;lombok&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/exclude&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/excludes&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-compiler-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.8.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;annotationProcessorPaths&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;path&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.projectlombok&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;lombok&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;${lombok.version}&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/path&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.projectlombok&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;lombok-mapstruct-binding&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;0.2.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/annotationProcessorPaths&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;compilerArgs&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;compilerArg&amp;gt;&lt;/span&gt;
                            -Amapstruct.defaultComponentModel=spring
                        &lt;span class="nt"&gt;&amp;lt;/compilerArg&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/compilerArgs&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; verifique as configurações do plugin do Lombok caso a aplicação não inicie corretamente.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2. Configuração dos &lt;code&gt;@Bean&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;O projeto utiliza uma classe com &lt;code&gt;@Configuration&lt;/code&gt; para definir os &lt;code&gt;@Bean&lt;/code&gt; principais:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductConfiguration&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;PRODUCT_REPOSITORY_BEAN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"productRepositoryBean"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;PRODUCT_SERVICE_BEAN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"productServiceBean"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Profile&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"!test"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
    &lt;span class="nd"&gt;@Bean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;PRODUCT_REPOSITORY_BEAN&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ProductRepository&lt;/span&gt; &lt;span class="nf"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProductJpaRepository&lt;/span&gt; &lt;span class="n"&gt;productJpaRepository&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ProductRepositoryImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;productJpaRepository&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;PRODUCT_SERVICE_BEAN&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ProductService&lt;/span&gt; &lt;span class="nf"&gt;productService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Qualifier&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;PRODUCT_REPOSITORY_BEAN&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;ProductRepository&lt;/span&gt; &lt;span class="n"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ProductServiceImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Atenção a notação &lt;code&gt;@Profile({"!test"})&lt;/code&gt;, aqui é informado que quando o &lt;strong&gt;profile&lt;/strong&gt; a ser executado contiver o valor &lt;strong&gt;teste&lt;/strong&gt; esse &lt;code&gt;@Bean&lt;/code&gt; deverá ficar sem ser ativado. Isso é importante para exemplificar o ponto aqui a ser passado.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3. Estrutura de Classes
&lt;/h3&gt;

&lt;p&gt;O projeto possui:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Product&lt;/code&gt; : entidade
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@JsonInclude&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JsonInclude&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Include&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NON_EMPTY&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Data&lt;/span&gt;
&lt;span class="nd"&gt;@Builder&lt;/span&gt;
&lt;span class="nd"&gt;@AllArgsConstructor&lt;/span&gt;
&lt;span class="nd"&gt;@NoArgsConstructor&lt;/span&gt;
&lt;span class="nd"&gt;@Entity&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"product"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Table&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"product"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Id&lt;/span&gt;
    &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GenerationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IDENTITY&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@Column&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Column&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Column&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"creation_date"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@JsonFormat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"yyyy-MM-dd'T'HH:mm:ss'Z'"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;LocalDateTime&lt;/span&gt; &lt;span class="n"&gt;creationDate&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ProductController&lt;/code&gt;: API Rest
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@EnableWebMvc&lt;/span&gt;
&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/product"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ProductService&lt;/span&gt; &lt;span class="n"&gt;productService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ProductController&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProductService&lt;/span&gt; &lt;span class="n"&gt;productService&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;productService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;productService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;produces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON_VALUE&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;consumes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON_VALUE&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;productService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CREATED&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ProductService&lt;/code&gt;: lógica de negócio
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ProductService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductServiceImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ProductService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ProductRepository&lt;/span&gt; &lt;span class="n"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ProductServiceImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProductRepository&lt;/span&gt; &lt;span class="n"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;productRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ProductRepository&lt;/code&gt;: camada de persistência
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ProductJpaRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JpaRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ProductRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductRepositoryImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ProductRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ProductJpaRepository&lt;/span&gt; &lt;span class="n"&gt;productJpaRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ProductRepositoryImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProductJpaRepository&lt;/span&gt; &lt;span class="n"&gt;productJpaRepository&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;productJpaRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;productJpaRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;productJpaRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.4. Fluxo da Aplicação
&lt;/h3&gt;

&lt;p&gt;O fluxo é &lt;code&gt;Controller → Service → Repository → Banco de Dados&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxu6uve847j290z1n1t5e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxu6uve847j290z1n1t5e.png" alt="Image description" width="800" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.5. &lt;code&gt;application.yml&lt;/code&gt; (ambiente dev)
&lt;/h3&gt;

&lt;p&gt;Quando se trabalha com Springboot uma das formas de se configurar as variáveis do projeto é através do arquivo &lt;strong&gt;application.yml&lt;/strong&gt;, sendo assim, a configuração do banco de dados também fica neste arquivo, segue um exemplo da configuração do projeto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;spring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;activate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;on-profile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev&lt;/span&gt;

  &lt;span class="na"&gt;jpa&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;defer-datasource-initialization&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;show-sql&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

  &lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jdbc:postgresql://localhost:5432/test&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test1234&lt;/span&gt;
    &lt;span class="na"&gt;driverClassName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;org.postgresql.Driver&lt;/span&gt;

&lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Teste de Integração com H2
&lt;/h2&gt;

&lt;p&gt;Ao realizar testes, é comum substituir o banco real por um banco em memória como o H2. Para isso:&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1. &lt;code&gt;application.yml&lt;/code&gt; para testes
&lt;/h3&gt;

&lt;p&gt;Arquivo localizado em &lt;code&gt;src/test/resources/&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;spring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;activate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;on-profile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;

  &lt;span class="na"&gt;jpa&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;defer-datasource-initialization&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;show-sql&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;hibernate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;ddl-auto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;create-drop&lt;/span&gt;

  &lt;span class="na"&gt;h2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

  &lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jdbc:h2:mem:test;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sa&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driverClassName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;org.h2.Driver&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2. Configuração dos &lt;code&gt;@Bean&lt;/code&gt; para teste
&lt;/h3&gt;

&lt;p&gt;Assim como em produção os &lt;code&gt;@Bean&lt;/code&gt; deverão ser mapeados, no caso em tela, o &lt;code&gt;@Bean&lt;/code&gt; relativo ao banco de dados deverá ser mapeado também. Repare que a notação mudou de &lt;code&gt;@Configuration&lt;/code&gt; para &lt;code&gt;@TestConfiguration&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@TestConfiguration&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ConfigTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Profile&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
    &lt;span class="nd"&gt;@Bean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProductConfiguration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PRODUCT_REPOSITORY_BEAN&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ProductRepository&lt;/span&gt; &lt;span class="nf"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProductJpaRepository&lt;/span&gt; &lt;span class="n"&gt;productJpaRepository&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ProductRepositoryImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;productJpaRepository&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Atenção a notação &lt;code&gt;@Profile({"test"})&lt;/code&gt;, aqui é informado que quando o &lt;strong&gt;profile&lt;/strong&gt; a ser executado contiver o valor &lt;strong&gt;teste&lt;/strong&gt; esse &lt;code&gt;@Bean&lt;/code&gt; deverá ser ativado. Isso é importante para exemplificar o ponto aqui a ser passado.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3. O Teste
&lt;/h3&gt;

&lt;p&gt;O ponto mais esperado chegou, o momento de criar o teste e vê-lo funcionar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ActiveProfiles&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;ConfigTest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="n"&gt;webEnvironment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SpringBootTest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;WebEnvironment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RANDOM_PORT&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@AutoConfigureMockMvc&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductControllerH2Test&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="nc"&gt;MockMvc&lt;/span&gt; &lt;span class="n"&gt;mockMvc&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt; &lt;span class="n"&gt;objectMapper&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@BeforeEach&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;beforeEach&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;objectMapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objectMapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;writeValueAsString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"new product"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

        &lt;span class="n"&gt;mockMvc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MockMvcRequestBuilders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/product/"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON_VALUE&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andExpect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MockMvcResultMatchers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isCreated&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andExpect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MockMvcResultMatchers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jsonPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.name"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"new product"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andExpect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MockMvcResultMatchers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jsonPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.id"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste ponto é importante observar algumas notações, tais quais &lt;code&gt;@ActiveProfiles({"test"})&lt;/code&gt; e &lt;br&gt;
&lt;code&gt;@SpringBootTest&lt;/code&gt; . A notação &lt;code&gt;@ActiveProfiles({"test"})&lt;/code&gt; indica que para executar os testes desta classe deverá ser ativado o &lt;strong&gt;profile test&lt;/strong&gt;, desta forma, excluindo outras configurações. Sobre a notação &lt;code&gt;@SpringBootTest&lt;/code&gt; foi explicado anteriormente sobre a sua função, no entanto, tem algo especificado dentro dela que é importante, que é &lt;code&gt;classes = {ConfigTest.class}&lt;/code&gt;, isso significa que a classe &lt;code&gt;ConfigTest.class&lt;/code&gt; deverá ser carregada no contexto do Spring quando o mesmo for inicializado.&lt;/p&gt;

&lt;p&gt;Repare que inexiste notações de &lt;strong&gt;mock&lt;/strong&gt; para os &lt;code&gt;@Bean&lt;/code&gt; do projeto, isso ocorreu pois de fato nada está sendo “mockado”, o fluxo ocorrerá do início ao fim, porém, o banco de dados utilizado será o &lt;strong&gt;H2&lt;/strong&gt; ao invés do banco utilizado em prod, dev, homolog ou algo do tipo que poderia ser um MySQL, PostgreSQL, Oracle ou outro.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. Teste de Integração com @MockBean
&lt;/h2&gt;

&lt;p&gt;Aqui, ao invés de usar um banco em memória, utilizamos mocks para simular o comportamento do repositório.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ActiveProfiles&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;ConfigTest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="n"&gt;webEnvironment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SpringBootTest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;WebEnvironment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RANDOM_PORT&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@AutoConfigureMockMvc&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductControllerMockTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="nc"&gt;MockMvc&lt;/span&gt; &lt;span class="n"&gt;mockMvc&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt; &lt;span class="n"&gt;objectMapper&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@MockBean&lt;/span&gt;
    &lt;span class="nc"&gt;ProductJpaRepository&lt;/span&gt; &lt;span class="n"&gt;productJpaRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@BeforeEach&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;beforeEach&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;objectMapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"new product"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;Mockito&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;productJpaRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenReturn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1L&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"test mock productJpaRepository"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objectMapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;writeValueAsString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;mockMvc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MockMvcRequestBuilders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/product/"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON_VALUE&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andExpect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MockMvcResultMatchers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isCreated&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andExpect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MockMvcResultMatchers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jsonPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.name"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"test mock productJpaRepository"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andExpect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MockMvcResultMatchers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jsonPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.id"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Atenção:&lt;/strong&gt; o &lt;code&gt;@MockBean&lt;/code&gt; precisa ser usado no ponto certo do fluxo. &lt;em&gt;Mockar&lt;/em&gt; classes fora da cadeia de execução esperada pode quebrar a injeção de dependências.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Quando usar H2 ou @MockBean?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Critério&lt;/th&gt;
&lt;th&gt;H2 (Banco em Memória)&lt;/th&gt;
&lt;th&gt;@MockBean (Simulação de Dependências)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fidelidade com banco real&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Alta (simula o banco de verdade com SQL real)&lt;/td&gt;
&lt;td&gt;❌ Baixa (lógica simulada, sem persistência real)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ Mais lento (carrega contexto + banco em memória)&lt;/td&gt;
&lt;td&gt;✅ Rápido (sem overhead de banco)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cobertura de integração&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Completa (inclui JPA, transações, etc.)&lt;/td&gt;
&lt;td&gt;❌ Limitada (testa só partes isoladas)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Manutenção de testes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⚠️ Média (precisa manter schema e dados consistentes)&lt;/td&gt;
&lt;td&gt;✅ Simples (mocka só o necessário)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Diagnóstico de bugs reais&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Melhor (simula situações reais de persistência)&lt;/td&gt;
&lt;td&gt;❌ Pode mascarar bugs que só aparecem com DB real&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Complexidade de setup&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ Alta (requires profile, config H2, beans específicos)&lt;/td&gt;
&lt;td&gt;✅ Baixa (só anotar com &lt;code&gt;@MockBean&lt;/code&gt; e boa)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Indicado para testes de...&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;🔍 Integração ponta-a-ponta, fluxo completo&lt;/td&gt;
&lt;td&gt;🧪 Lógica de negócio, regras isoladas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Depende de schema do banco?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Sim&lt;/td&gt;
&lt;td&gt;❌ Não&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ideal para TDD?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ Não (mais lento e complexo)&lt;/td&gt;
&lt;td&gt;✅ Sim (rápido e direto ao ponto)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Pode-se considerar então que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use &lt;strong&gt;H2&lt;/strong&gt; se quiser testar o comportamento completo da aplicação, incluindo a persistência real de dados.&lt;/li&gt;
&lt;li&gt;use &lt;strong&gt;@MockBean&lt;/strong&gt; para testar lógica de negócio de forma isolada, sem depender da infraestrutura.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ambas técnicas são válidas e, inclusive, complementares.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Links de Referência
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/rpedroni/tudo-sobre-testes-testes-unit%C3%A1rios-vs-testes-de-integra%C3%A7%C3%A3o-vs-testes-e2e-6a7cc955779" rel="noopener noreferrer"&gt;Tipos de testes: unitário, integração, E2E&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@leonardogiuliani/autowired-e-a-inje%C3%A7%C3%A3o-de-depend%C3%AAncia-do-spring-d8864cc9af50" rel="noopener noreferrer"&gt;Injeção de dependência com @Autowired&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.baeldung.com/spring-component-repository-service" rel="noopener noreferrer"&gt;Anotações do Spring: @Component, @Service, @Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jeffersonfabriciodev/o-uso-do-autowired-no-spring-%C3%A9-uma-m%C3%A1-pratica-a23378be3c27" rel="noopener noreferrer"&gt;Problemas com o uso de @Autowired&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Se você leu até aqui, parabéns: agora tem munição suficiente pra escrever testes robustos no Spring Boot. Se não escrever, o bug vai te pegar! 😂&lt;/p&gt;




</description>
      <category>springboot</category>
      <category>mockbean</category>
      <category>testing</category>
      <category>h2</category>
    </item>
    <item>
      <title>Debug Golang com VSCode</title>
      <dc:creator>Mairon Costa</dc:creator>
      <pubDate>Fri, 06 Jan 2023 19:09:46 +0000</pubDate>
      <link>https://dev.to/maironmscosta/debug-golang-com-vscode-2dhn</link>
      <guid>https://dev.to/maironmscosta/debug-golang-com-vscode-2dhn</guid>
      <description>&lt;p&gt;Opa, fala aí, pessoal, tudo beleza!? Depois de muito tempo sem escrever algo eu estou aparecendo aqui com esse mini tutorial (ou “how to” como alguns chamam) para explicar como configurar o VSCode para que se possa debugar ao desenvolver em Go (Golang). A minha principal motivação vem da galera com a qual eu trabalho, pois muitos têm dado preferência a utilizar o VSCode para desenvolver e, quando eles precisam de alguma ajuda ou tem alguma dúvida, que eu paro para tentar ajudá-los, eles colocam alguns println para entender o fluxo do sistema e para tentar saber o valor que determinada variável possui e por aí vai. Com isso, acabam repetindo as mesmas ações e outras coisas mais que acabam dificultando o entendimento e a resolver a questão. Como eu sou de uma geração um pouco mais antiga, eu desde cedo fui moldado a utilizar o debug na qual as IDEs disponibilizam e eu achei estranho - até meio improdutivo, isso alinhado a tortura do println - essa galera mais nova adicionar um monte de println ao código e depois sair removendo tudo quando vão realizar o commit.&lt;/p&gt;

&lt;p&gt;Bem. Eu já falei (eu quis dizer escrever, mas você entendeu) demais. Vamos ao que interessa!&lt;/p&gt;

&lt;h2&gt;
  
  
  Sumário
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sistema e Configurações&lt;/li&gt;
&lt;li&gt;Pré-Requisitos

&lt;ul&gt;
&lt;li&gt;Instalar Go no VSCode&lt;/li&gt;
&lt;li&gt;Instalar o DLV no VSCode&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Template básico do arquivo de configuração&lt;/li&gt;

&lt;li&gt;Configurando o projeto&lt;/li&gt;

&lt;li&gt;Inicializando a aplicação no modo debug&lt;/li&gt;

&lt;li&gt;Conclusão&lt;/li&gt;

&lt;li&gt;Referências&lt;/li&gt;

&lt;li&gt;Apêndices&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sistema e Configurações
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Pop!_OS versão 22.04 LTS em Máquina Virtual (VM);&lt;/li&gt;
&lt;li&gt;  Go na versão 1.19.4 instalado via GVM;&lt;/li&gt;
&lt;li&gt;  VSCode versão 1.74.1 instalado via flatpak;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pré-Requisitos
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Instalar Go no VSCode
&lt;/h3&gt;

&lt;p&gt;Para esse tutorial foi utilizado a extensão Go na versão 0.37.0 da empresa &lt;em&gt;Go team at Google&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instalar o &lt;em&gt;DLV&lt;/em&gt; no VSCode
&lt;/h3&gt;

&lt;p&gt;Para tirar maior proveito na manutenção e assim manter atualizado o modo debug, pode-se utilizar o &lt;em&gt;dlv&lt;/em&gt;. O jeito mais fácil de instalar o &lt;em&gt;dlv&lt;/em&gt; é utilizar o comando "&lt;code&gt;Go: Install/Update Tools&lt;/code&gt;" na paleta de comando do VSCode (Linux/Windows: Ctrl+Shift+P). O comando mostrará o &lt;em&gt;dlv&lt;/em&gt; na listagem de ferramentas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Template básico do arquivo de configuração
&lt;/h2&gt;

&lt;p&gt;Para usar o modo debug no VSCode será necessário ter na raíz do projeto a pasta &lt;code&gt;.vscode&lt;/code&gt; e dentro dela o arquivo launch.json, assim ficando &lt;code&gt;/.vscode/launch.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| raíz_projeto
| - .vscode
| - - launch.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A seguir, um template básico do &lt;code&gt;launch.json&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; {
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Run Name",
            "type": "go",
            "request": "launch",
            "mode": "debug",
            "program": "${workspaceFolder}",
            "env": {},
            "args": [],
            "showLog": true
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;${workspaceFolder} é uma variável de ambiente gerada pelo VSCode que corresponde ao diretório raíz da aplicação.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Configurando o projeto
&lt;/h2&gt;

&lt;p&gt;Para ter um exemplo mais concreto do uso será utilizado um projeto de exemplo como base para demonstrar as configurações.&lt;/p&gt;

&lt;p&gt;Estrutura base do projeto:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| test-debug
| - .vscode
| - - launch.json
| - cmd
| - - main.go
| - envfile.env
| - go.mod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;É possível ter mais de uma configuração no mesmo &lt;code&gt;launch.json&lt;/code&gt; para ser utilizada de acordo com a necessidade, ou seja, é desnecessário ter mais de um &lt;code&gt;launch.json&lt;/code&gt; ou então ficar alterando as configurações do mesmo para obter configurações diferentes. Em outras palavras, significa que dentro do mesmo &lt;code&gt;launch.json&lt;/code&gt; é possível ter uma configuração para inicializar a aplicação com configurações para ambiente de dev, ambiente de homologação, de produção e assim por diante.&lt;/p&gt;

&lt;p&gt;Vejamos a seguir exemplo de configuração para inicializar a aplicação:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Arquivo &lt;code&gt;launch.json&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "version":"0.2.0",
    "configurations":[
        {
            "name":"Test: Simple",
            "type":"go",
            "request":"launch",
            "mode":"debug",
            "program":"${workspaceFolder}/cmd",
            "env":{},
            "args":[],
            "showLog":true
        },
        {
            "name":"Test: Env And Args",
            "type":"go",
            "request":"launch",
            "mode":"debug",
            "program":"${workspaceFolder}/cmd",
            "envFile":"${workspaceFolder}/envfile.env",
            "env":{
                "HOST":"test.com"
            },
            "args":[
                "redirect",
                "test"
            ],
            "showLog":true
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Repare que na configuração que corresponde a &lt;em&gt;Test: Env And Args&lt;/em&gt; foi utilizado um arquivo que contém algumas variáveis de ambiente, *&lt;em&gt;, tem o *env&lt;/em&gt; no qual é possível também declarar variáveis de ambiente e o &lt;em&gt;args&lt;/em&gt;, que é utilizado para passar argumentos a aplicação. Todos esses atributos possibilitam passar dados a aplicação.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Arquivo &lt;code&gt;envfile.env&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENVIRONMENT=dev
MESSAGE=HELLO WORLD!
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Desta forma, seria possível externalizar num arquivo &lt;em&gt;.env&lt;/em&gt; as variáveis de ambiente que são comuns aos ambientes, ou seja, simplifica a configuração.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Arquivo &lt;code&gt;main.go&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main
import (
    "fmt"
    "os"
)

func main() {
    HOST := os.Getenv("HOST")
    MESSAGE := os.Getenv("MESSAGE")
    ENVIRONMENT := os.Getenv("ENVIRONMENT")
    args := os.Args

    // without these println there is a compile error
    fmt.Println(fmt.Sprintf("Host: %s; Message: %s; Environment: %s", HOST, MESSAGE, ENVIRONMENT))

    for  i, arg := range args {
        fmt.Println(fmt.Sprintf("arg(%d): %s ", i, arg))
    }

}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ao executar o programa será possível visualizar todas as variáveis e seus respectivos valores no &lt;em&gt;painel de variáveis&lt;/em&gt; do VSCode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvmbcj73dwqmwnwljen22.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvmbcj73dwqmwnwljen22.png" alt="painel_variaveis.png" width="442" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inicializando a aplicação no modo debug
&lt;/h2&gt;

&lt;p&gt;Para inicializar a aplicação é bem simples, só seguir os seguintes passos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;clicar no ícone &lt;em&gt;Run and Debug&lt;/em&gt; que fica, por padrão, do lado esquerdo do VSCode;&lt;/li&gt;
&lt;li&gt;selecionar qual configuração do &lt;em&gt;launch.json&lt;/em&gt; se deseja executar;&lt;/li&gt;
&lt;li&gt;adicionar breakpoint no ponto que deseja pausar a execução da aplicação;&lt;/li&gt;
&lt;li&gt;clicar no botão &lt;em&gt;Start Debugging (F5)&lt;/em&gt; - ou &lt;em&gt;Iniciar Depuração (F5)&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnz9fvdwvzbgjqmb13l7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnz9fvdwvzbgjqmb13l7.png" alt="iniciar_aplicacao_debug.png" width="623" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Com o passo-a-passo descrito eu espero que agora seja possível configurar o ambiente de desenvolvimento, fazendo uso das configurações no &lt;code&gt;launch.json&lt;/code&gt; e, a debuggar a aplicação, para que se possa acompanhar o fluxo do sistema e suas variáveis, desta forma, melhorando a produtividade e o entendimento durante o desenvolvimento.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/golang/vscode-go/blob/master/docs/debugging.md" rel="noopener noreferrer"&gt;https://github.com/golang/vscode-go/blob/master/docs/debugging.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/debugging-go-code-with-visual-studio-code" rel="noopener noreferrer"&gt;https://www.digitalocean.com/community/tutorials/debugging-go-code-with-visual-studio-code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Apêndices
&lt;/h2&gt;

&lt;p&gt;A seguir algumas informações sobre as tecnologias utilizadas para desenvolver esse exemplo de aplicação:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; SO utilizado &lt;a href="https://pop.system76.com" rel="noopener noreferrer"&gt;Pop!_OS versão 22.04 LTS&lt;/a&gt; &lt;/li&gt;
&lt;li&gt; Máquina Virtual (VM) foi utilizado o &lt;a href="https://flathub.org/apps/details/org.gnome.Boxes" rel="noopener noreferrer"&gt;Gnome Boxes&lt;/a&gt; via flatpak;&lt;/li&gt;
&lt;li&gt;  Go na versão 1.19.4 instalado via &lt;a href="https://github.com/moovweb/gvm#installing" rel="noopener noreferrer"&gt;GVM&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://flathub.org/apps/details/com.visualstudio.code" rel="noopener noreferrer"&gt;VSCode versão 1.74.1&lt;/a&gt; instalado via flatpak;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>emptystring</category>
    </item>
    <item>
      <title>AWS Lambda com Localstack</title>
      <dc:creator>Mairon Costa</dc:creator>
      <pubDate>Tue, 26 May 2020 01:43:19 +0000</pubDate>
      <link>https://dev.to/maironmscosta/aws-lambda-com-localstack-fe6</link>
      <guid>https://dev.to/maironmscosta/aws-lambda-com-localstack-fe6</guid>
      <description>&lt;p&gt;for english, &lt;a href="https://dev.to/maironmscosta/aws-lambda-with-localstack-32hc"&gt;click here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hoje em dia é muito comum ver as pessoas fazendo uso de plataformas de serviços online como a &lt;a href="https://aws.amazon.com/"&gt;AWS&lt;/a&gt;, &lt;a href="https://azure.microsoft.com/"&gt;Azure&lt;/a&gt;, &lt;a href="https://cloud.google.com/"&gt;GoogleCloud&lt;/a&gt;. Estes são as mais famosas &lt;a href="https://www.oracle.com/cloud/what-is-Cloud-computing/"&gt;"Cloud"&lt;/a&gt;. E, como qualquer outro desenvolvedor, é muito importante testar seus códigos antes de colocá-lo em produção, e neste caso, algumas questões surgem, "Como é possível testar o código que está em produção?", "Como eu posso atualizar o código que já funciona sem quebrá-lo?" ou algo do tipo.  Então, para estes casos, este trabalho foi pensado. A meta principal é explicar como é possível testar um &lt;a href="https://aws.amazon.com/lambda/?nc1=h_ls"&gt;AWS Lambda&lt;/a&gt; na sua máquina usando PyCharm com Python e Localstack.&lt;/p&gt;

&lt;p&gt;Então... vamos lá!!!!!&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu 20.04 LTS;&lt;/li&gt;
&lt;li&gt;IDE: PyCharm Professional;&lt;/li&gt;
&lt;li&gt;Python 3.8;&lt;/li&gt;
&lt;li&gt;Docker;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html"&gt;AWS SAM CLI&lt;/a&gt;:  é necessário para IDE funcionar com AWS Services;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html"&gt;AWS CLI&lt;/a&gt;: você pode usar suas credenciais verdadeiras (como descrito &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html"&gt;aqui&lt;/a&gt;), ou pode fazer uma ficticia. O Localstack verifica se as credenciais estão presentes e não se elas são válidas;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://serverless.com/"&gt;Serverless&lt;/a&gt; framework;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuração
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AWS CLI
&lt;/h3&gt;

&lt;p&gt;Sobre o &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html"&gt;AWS CLI&lt;/a&gt;, é possível checar o material para instalar no site da AWS, &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html"&gt;clique aqui&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  AWS SAM CLI
&lt;/h3&gt;

&lt;p&gt;Para instalar o &lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html"&gt;AWS SAM CLI&lt;/a&gt; é informado nos documentos da AWS que é para instalá-lo pelo Homebrew, mas em alguns casos é difícil instalar o Homebrew e pensando nisto, aqui está um outro jeito de instalar o &lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html"&gt;AWS SAM CLI&lt;/a&gt;, é possíve pegar o código fonte no Github &lt;a href="https://github.com/awslabs/aws-sam-cli"&gt;clicando aqui&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/awslabs/aws-sam-cli.git
$ cd aws-sam-cli
$ sudo python3.8 ./setup.py build install
$ sam --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A saída final:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SAM CLI, version 0.47.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Localstack Docker
&lt;/h3&gt;

&lt;p&gt;Neste momento o "docker-compose.yaml" deve ser criado na raíz do projeto,  com isto será possível rodar o localstack de um docker container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ touch docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;docker-compose.yml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '2.1'
services:    
  localstack:  
    image: localstack/localstack  
    ports:  
      - "4567-4597:4567-4597"  
      - "${PORT_WEB_UI-8080}:${PORT_WEB_UI-8080}"  
    environment:  
      - SERVICES=${SERVICES- }  
      - DEBUG=${DEBUG- }  
      - DATA_DIR=${DATA_DIR- }  
      - PORT_WEB_UI=${PORT_WEB_UI- }  
      - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR- }  
      - KINESIS_ERROR_PROBABILITY=${KINESIS_ERROR_PROBABILITY- }  
      - DOCKER_HOST=unix:///var/run/docker.sock  
    volumes:  
      - "${TMPDIR:-/tmp/localstack}:/tmp/localstack"  
      - "/var/run/docker.sock:/var/run/docker.sock"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E agora vamos rodar o "docker-compose" com o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A partir deste momento é possível acessar diferentes serviços da AWS atráves das diferentes portas no servidor local. Por enquanto vamos testar o serviço do AWS S3.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -v http://localhost:4572
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parte da saída:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01"&amp;gt;
    &amp;lt;Owner&amp;gt;&amp;lt;ID&amp;gt;bcaf1ffd86f41161ca5fb16fd081034f&amp;lt;/ID&amp;gt;                
    &amp;lt;DisplayName&amp;gt;webfile&amp;lt;/DisplayName&amp;gt;&amp;lt;/Owner&amp;gt;&amp;lt;Buckets&amp;gt;&amp;lt;/Buckets&amp;gt;
&amp;lt;/ListAllMyBucketsResult&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este teste pode ser realizado também no browser. Apenas copie o endereço e cole na url do browser ou apenas &lt;a href="http://localhost:4572"&gt;click aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Algumas portas do AWS Service com Localstack&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;S3&lt;/strong&gt;: 4572&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB&lt;/strong&gt;: 4570&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudFormation&lt;/strong&gt;: 4581&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elasticsearch&lt;/strong&gt;: 4571&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ES&lt;/strong&gt;: 4578&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SNS&lt;/strong&gt;: 4575&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQS&lt;/strong&gt;: 4576&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lambda&lt;/strong&gt;: 4574&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kinesis&lt;/strong&gt;: 4568&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  PyCharm com AWS Lambda
&lt;/h3&gt;

&lt;p&gt;Uma vez o "docker-compose" estiver funcionando é hora de criar o projeto. Neste momento vamos criar um projeto novo no PyCharm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Criando um no projeto: &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv9af03m99x8pnpb6p0mp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv9af03m99x8pnpb6p0mp.png" alt="image 01" width="775" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No passo número 3 é muito importante checar se o "SAM CLI" foi automáticamente reconhecido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxm89qi465px2q1p4fruy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxm89qi465px2q1p4fruy.png" alt="image 02" width="775" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Criando o arquivo principal, o

&lt;code&gt;lambda_function.py&lt;/code&gt;

, na raíz do projeto.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import urllib.parse
import boto3
import json

# print('Loading function')

HOST = "http://[YOUR_IP]"
# Get the service resource
# To production it's not necessary inform the "endpoint_url" and "region_name"
s3 = boto3.client('s3',
                  endpoint_url= HOST + ":4572",
                  region_name="us-east-1")
sqs = boto3.client('sqs',
                  endpoint_url= HOST + ":4576",
                  region_name="us-east-1")

def lambda_handler(event, context):
    # print("Received event: " + json.dumps(event, indent=2))

    # Get the object from the event and show its content type
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    url_queue = HOST + ":4576/queue/lambda-tutorial"

    try:

        response = s3.get_object(Bucket=bucket, Key=key)

        deb = {
            "request_id": response['ResponseMetadata']['RequestId'],
            "queue_url": url_queue,
            "key": key,
            "bucket": bucket,
            "message": "aws lambda with localstack..."
        }

        print("#########################################################")
        print("Send Message")
        #Send message to SQS queue
        response = sqs.send_message(
                QueueUrl=deb["queue_url"],
                MessageBody=json.dumps(deb)
        )

        print("response: {}".format(response))

        print("#########################################################")
        print("Receive 10 Messages From SQS Queue")
        response = sqs.receive_message(
            QueueUrl=deb["queue_url"],
            MaxNumberOfMessages=10,
            VisibilityTimeout=0,
            WaitTimeSeconds=0
        )

        print("#########################################################")
        print("Read All Messages From Response")
        messages = response['Messages']
        for message in messages:
            print("Message: {}".format(message))

        print("Final Output: {}".format(json.dumps(response)))
        return json.dumps(response)

    except Exception as e:
        print(e)
        raise e
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Se o "boto3" não estiver instalado a IDE irá notificar, assim sendo, abra o terminal e execute o seguinte comando:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ pip3.8 install boto3&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Criando os arquivos que darão suporte ao projeto.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neste momento algumas pastas e arquivos serão criados, as pastas conterão os arquivos utilizados no teste. Vamos criar as pastas "test/files" na raíz do projeto e então criar os arquivo para rodar o projeto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws-lambda-localstack
|test/
|- file/
|- - test_file.log
|- - input-event-test.json
|requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;test_file.log&lt;/strong&gt;: Este arquivo será usado como exemplo vindo do bucket. Pode ser um arquivo vazio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;requirements.txt&lt;/strong&gt;: Este arquivo é exigido pelo "SAM CLI".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;input-event-test.json&lt;/strong&gt;: Este arquivo será executado para rodar o projeto. Ele contém as informações do bucket.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Records": [
    {
      "eventVersion": "2.0",
      "eventSource": "aws:s3",
      "awsRegion": "us-east-1",
      "eventTime": "1970-01-01T00:00:00.000Z",
      "eventName": "ObjectCreated:Put",
      "userIdentity": {
        "principalId": "EXAMPLE"
      },
      "requestParameters": {
        "sourceIPAddress": "127.0.0.1"
      },
      "responseElements": {
        "x-amz-request-id": "EXAMPLE123456789",
        "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
      },
      "s3": {
        "s3SchemaVersion": "1.0",
        "configurationId": "testConfigRule",
        "bucket": {
          "name": "tutorial",
          "ownerIdentity": {
            "principalId": "EXAMPLE"
          },
          "arn": "arn:aws:s3:::example-bucket"
        },
        "object": {
          "key": "lambda/test_file.log",
          "size": 1024,
          "eTag": "0123456789abcdef0123456789abcdef",
          "sequencer": "0A1B2C3D4E5F678901"
        }
      }
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Uma vez que os passos anteriores estivem terminados, o próximo passo será configurar o "run configuration".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flcb6dynn23csq1v8np0m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flcb6dynn23csq1v8np0m.png" alt="image 03-pycharm-run-configuration" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd2sys59j4t20d07rk72t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd2sys59j4t20d07rk72t.png" alt="image-03-pycharm-run-configuration-aws-connection" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora a configuração de IDE está feita, hora de configurar as entradas. Para configurar as entradas é obrigatório rodar alguns comando para criar os arquivos no S3 e criar a fila no SQS.&lt;/p&gt;

&lt;p&gt;1 - Criando o bucket no S3: o bucket será nomeado como "tutorial".&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ aws --endpoint-url=http://localhost:4572 s3 mb s3://tutorial&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;2 -  Criando a pasta no S3: será criada uma pasta chamada "lambda".&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ aws --endpoint-url=http://localhost:4572 s3api put-object --bucket tutorial --key lambda&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;O Response será alguma como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\""
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 - Copiando arquivos para o bucket: copiando os arquivos de "test/files" para "s3://tutorial/lambda/".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws --endpoint-url=http://localhost:4572 s3 cp ./test/files/ s3://tutorial/lambda/ --recursive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deve-se checar se o bucket foi criado. Copie o valor de "endpoint-url" e execute um "curl" ou cole no browser, por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -v http://localhost:4572/tutorial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A saída será algo como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"&amp;gt;
   &amp;lt;Name&amp;gt;tutorial&amp;lt;/Name&amp;gt;
   &amp;lt;MaxKeys&amp;gt;1000&amp;lt;/MaxKeys&amp;gt;
   &amp;lt;Delimiter&amp;gt;None&amp;lt;/Delimiter&amp;gt;
   &amp;lt;IsTruncated&amp;gt;false&amp;lt;/IsTruncated&amp;gt;
   &amp;lt;Contents&amp;gt;
      &amp;lt;Key&amp;gt;lambda&amp;lt;/Key&amp;gt;
      &amp;lt;LastModified&amp;gt;2020-04-28T01:36:04.128Z&amp;lt;/LastModified&amp;gt;
      &amp;lt;ETag&amp;gt;"d41d8cd98f00b204e9800998ecf8427e"&amp;lt;/ETag&amp;gt;
      &amp;lt;Size&amp;gt;0&amp;lt;/Size&amp;gt;
      &amp;lt;StorageClass&amp;gt;STANDARD&amp;lt;/StorageClass&amp;gt;
      &amp;lt;Owner&amp;gt;
         &amp;lt;ID&amp;gt;75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a&amp;lt;/ID&amp;gt;
         &amp;lt;DisplayName&amp;gt;webfile&amp;lt;/DisplayName&amp;gt;
      &amp;lt;/Owner&amp;gt;
   &amp;lt;/Contents&amp;gt;
   &amp;lt;Contents&amp;gt;
      &amp;lt;Key&amp;gt;lambda/input-event-test.json&amp;lt;/Key&amp;gt;
      &amp;lt;LastModified&amp;gt;2020-04-28T01:40:27.882Z&amp;lt;/LastModified&amp;gt;
      &amp;lt;ETag&amp;gt;"4e114da7aa17878f62bf4485a90a97a2"&amp;lt;/ETag&amp;gt;
      &amp;lt;Size&amp;gt;1011&amp;lt;/Size&amp;gt;
      &amp;lt;StorageClass&amp;gt;STANDARD&amp;lt;/StorageClass&amp;gt;
      &amp;lt;Owner&amp;gt;
         &amp;lt;ID&amp;gt;75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a&amp;lt;/ID&amp;gt;
         &amp;lt;DisplayName&amp;gt;webfile&amp;lt;/DisplayName&amp;gt;
      &amp;lt;/Owner&amp;gt;
   &amp;lt;/Contents&amp;gt;
   &amp;lt;Contents&amp;gt;
      &amp;lt;Key&amp;gt;lambda/test_file.log&amp;lt;/Key&amp;gt;
      &amp;lt;LastModified&amp;gt;2020-04-28T01:40:27.883Z&amp;lt;/LastModified&amp;gt;
      &amp;lt;ETag&amp;gt;"4ac646c9537443757aff7ebd0df4f448"&amp;lt;/ETag&amp;gt;
      &amp;lt;Size&amp;gt;29&amp;lt;/Size&amp;gt;
      &amp;lt;StorageClass&amp;gt;STANDARD&amp;lt;/StorageClass&amp;gt;
      &amp;lt;Owner&amp;gt;
         &amp;lt;ID&amp;gt;75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a&amp;lt;/ID&amp;gt;
         &amp;lt;DisplayName&amp;gt;webfile&amp;lt;/DisplayName&amp;gt;
      &amp;lt;/Owner&amp;gt;
   &amp;lt;/Contents&amp;gt;
&amp;lt;/ListBucketResult&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4 - Criando um fila no SQS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws --endpoint-url=http://localhost:4576 sqs create-queue --queue-name lambda-tutorial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O retorno será algo como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "QueueUrl": "http://localhost:4576/queue/lambda-tutorial"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uma vez que tudo estiver feito e todas as saídas estão okays, é hora de rodar o projeto. Note que, no código foi inscrito a entrada e a saída pra este texto. Assim sendo, para rodar o projeto clique no botão "Run '[Local] lambda_function.lambda_handler'".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvxpjii26t2fzx0o8sv6x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvxpjii26t2fzx0o8sv6x.png" alt="image-04-pycharm-run-project" width="800" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois disto, é possível ver a saída do processo no console. É exibido as entradas e ao final dez mensagens serão recuperadas da fila e exibidas no console.&lt;/p&gt;

&lt;p&gt;BOA!&lt;/p&gt;

&lt;h2&gt;
  
  
  Concluído!
&lt;/h2&gt;

&lt;p&gt;Este pode ser somente o ponto inicial e eu espero que este texto ajude-os a testar seus serviços na AWS... Eu espero que todos vocês alcancem suas metas.&lt;/p&gt;

&lt;p&gt;Repositório: &lt;a href="https://bitbucket.org/MaironCosta/aws-lambda-localstack/src/master/"&gt;aws-lambda-localstack&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Obrigado por ter lido até o fim!&lt;/p&gt;

&lt;h3&gt;
  
  
  Referências
&lt;/h3&gt;

&lt;p&gt;Algumas referências que foram utilizadas para concluir este texto.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html"&gt;AWS SAM CLI&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html"&gt;AWS CLI&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://serverless.com/"&gt;Serverless&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/localstack/localstack"&gt;Localstack&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/manomano-tech/using-serverless-framework-localstack-to-test-your-aws-applications-locally-17748ffe6755"&gt;Using Serverless Framework &amp;amp; Localstack to test your AWS applications locally&lt;/a&gt;;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Algumas Cloud Computing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/"&gt;AWS&lt;/a&gt;; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://azure.microsoft.com/"&gt;Azure&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cloud.google.com/"&gt;GoogleCloud&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.openshift.com/"&gt;Openshift&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.oracle.com/cloud/"&gt;Oracle&lt;/a&gt;;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>lambda</category>
      <category>localstack</category>
      <category>serverless</category>
      <category>python</category>
    </item>
    <item>
      <title>AWS Lambda with Localstack</title>
      <dc:creator>Mairon Costa</dc:creator>
      <pubDate>Tue, 26 May 2020 01:29:08 +0000</pubDate>
      <link>https://dev.to/maironmscosta/aws-lambda-with-localstack-32hc</link>
      <guid>https://dev.to/maironmscosta/aws-lambda-with-localstack-32hc</guid>
      <description>&lt;h1&gt;
  
  
  AWS Lambda with Localstack
&lt;/h1&gt;

&lt;p&gt;for portguese, &lt;a href="https://blog.geekhunter.com.br/aws-lambda-python-pycharm-localstack/"&gt;click here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Nowadays it's very common to see people using online platform stacks services like the &lt;a href="https://aws.amazon.com/"&gt;AWS&lt;/a&gt;, &lt;a href="https://azure.microsoft.com/"&gt;Azure&lt;/a&gt;, &lt;a href="https://cloud.google.com/"&gt;GoogleCloud&lt;/a&gt;. They're the most famous &lt;a href="https://www.oracle.com/cloud/what-is-Cloud-computing/"&gt;"Cloud"&lt;/a&gt;. And, as anything as others developer, it's very important to test your code before putting it on production, and in this case, some question shows up, "How is possible to test the code that is in production?",  "How could I update a code that works without broke it?" or something like that. And so, to these cases, this work was thought. The main goal is to explain how it's possible to run an &lt;a href="https://aws.amazon.com/lambda/?nc1=h_ls"&gt;AWS Lambda&lt;/a&gt; in a machine using PyCharm with python and localstack.&lt;/p&gt;

&lt;p&gt;and so... let's go!&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu 20.04 LTS;&lt;/li&gt;
&lt;li&gt;IDE: PyCharm Professional;&lt;/li&gt;
&lt;li&gt;Python 3.8;&lt;/li&gt;
&lt;li&gt;Docker;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html"&gt;AWS SAM CLI&lt;/a&gt;: It's necessary to IDE works with AWS Services;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html"&gt;AWS CLI&lt;/a&gt;: You can use real credentials (as described &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html"&gt;here&lt;/a&gt;), or dummy ones. Localstack requires that these values are present, but it doesn’t validate them;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://serverless.com/"&gt;Serverless&lt;/a&gt; framework;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AWS CLI
&lt;/h3&gt;

&lt;p&gt;About the &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html"&gt;AWS CLI&lt;/a&gt;, it's possible to check the AWS material to install it, &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html"&gt;click here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS SAM CLI
&lt;/h3&gt;

&lt;p&gt;To install the &lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html"&gt;AWS SAM CLI&lt;/a&gt; is informed in the AWS docs that it's necessary to install it by Homebrew, but in some cases is hard to install the Homebrew, and thinking about this, there is another way to install it, it's possible to get the source code from Github repository &lt;a href="https://github.com/awslabs/aws-sam-cli"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/awslabs/aws-sam-cli.git
$ cd aws-sam-cli
$ sudo python3.8 ./setup.py build install
$ sam --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SAM CLI, version 0.47.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Localstack Docker
&lt;/h3&gt;

&lt;p&gt;At this time, the "docker-compose.yaml" have to be created at the root of the project. With this, it will be possible to run localstack from a docker container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ touch docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;docker-compose.yml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '2.1'
services:    
  localstack:  
    image: localstack/localstack  
    ports:  
      - "4567-4597:4567-4597"  
      - "${PORT_WEB_UI-8080}:${PORT_WEB_UI-8080}"  
    environment:  
      - SERVICES=${SERVICES- }  
      - DEBUG=${DEBUG- }  
      - DATA_DIR=${DATA_DIR- }  
      - PORT_WEB_UI=${PORT_WEB_UI- }  
      - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR- }  
      - KINESIS_ERROR_PROBABILITY=${KINESIS_ERROR_PROBABILITY- }  
      - DOCKER_HOST=unix:///var/run/docker.sock  
    volumes:  
      - "${TMPDIR:-/tmp/localstack}:/tmp/localstack"  
      - "/var/run/docker.sock:/var/run/docker.sock"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now, let's run the docker-compose with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it's possible to access different AWS services through different ports on your local server. For a while, let's test the AWS S3 service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -v http://localhost:4572
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some part of output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01"&amp;gt;
    &amp;lt;Owner&amp;gt;&amp;lt;ID&amp;gt;bcaf1ffd86f41161ca5fb16fd081034f&amp;lt;/ID&amp;gt;                
    &amp;lt;DisplayName&amp;gt;webfile&amp;lt;/DisplayName&amp;gt;&amp;lt;/Owner&amp;gt;&amp;lt;Buckets&amp;gt;&amp;lt;/Buckets&amp;gt;
&amp;lt;/ListAllMyBucketsResult&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This test can be done in the web browser, too. Just copy the address and then paste it in the browser URL or just click &lt;a href="http://localhost:4572"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some ports from AWS Service with Localstack&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;S3&lt;/strong&gt;: 4572&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB&lt;/strong&gt;: 4570&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudFormation&lt;/strong&gt;: 4581&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elasticsearch&lt;/strong&gt;: 4571&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ES&lt;/strong&gt;: 4578&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SNS&lt;/strong&gt;: 4575&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQS&lt;/strong&gt;: 4576&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lambda&lt;/strong&gt;: 4574&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kinesis&lt;/strong&gt;: 4568&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  PyCharm with AWS Lambda
&lt;/h3&gt;

&lt;p&gt;Once the docker-compose it's working and running, it's time to create the project. Let's create a new project in the PyCharm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating a new project &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv9af03m99x8pnpb6p0mp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv9af03m99x8pnpb6p0mp.png" alt="image 01" width="775" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In step number 3 it's very important to check if the "SAM CLI" was automatically recognized.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxm89qi465px2q1p4fruy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxm89qi465px2q1p4fruy.png" alt="image 02" width="775" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating the main file, the

&lt;code&gt;lambda_function.py&lt;/code&gt;

, in the root of the project.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import urllib.parse
import boto3
import json

# print('Loading function')

HOST = "http://[YOUR_IP]"
# Get the service resource
# To production it's not necessary inform the "endpoint_url" and "region_name"
s3 = boto3.client('s3',
                  endpoint_url= HOST + ":4572",
                  region_name="us-east-1")
sqs = boto3.client('sqs',
                  endpoint_url= HOST + ":4576",
                  region_name="us-east-1")

def lambda_handler(event, context):
    # print("Received event: " + json.dumps(event, indent=2))

    # Get the object from the event and show its content type
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    url_queue = HOST + ":4576/queue/lambda-tutorial"

    try:

        response = s3.get_object(Bucket=bucket, Key=key)

        deb = {
            "request_id": response['ResponseMetadata']['RequestId'],
            "queue_url": url_queue,
            "key": key,
            "bucket": bucket,
            "message": "aws lambda with localstack..."
        }

        print("#########################################################")
        print("Send Message")
        #Send message to SQS queue
        response = sqs.send_message(
                QueueUrl=deb["queue_url"],
                MessageBody=json.dumps(deb)
        )

        print("response: {}".format(response))

        print("#########################################################")
        print("Receive 10 Messages From SQS Queue")
        response = sqs.receive_message(
            QueueUrl=deb["queue_url"],
            MaxNumberOfMessages=10,
            VisibilityTimeout=0,
            WaitTimeSeconds=0
        )

        print("#########################################################")
        print("Read All Messages From Response")
        messages = response['Messages']
        for message in messages:
            print("Message: {}".format(message))

        print("Final Output: {}".format(json.dumps(response)))
        return json.dumps(response)

    except Exception as e:
        print(e)
        raise e
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;If the "boto3" is not installed the IDE will warning, and so, open a terminal and executing the following command&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ pip3.8 install boto3&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating files that will support the project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this time, there are some folders and files to be created, the folders must contain the files test. Let's create the folders "test/files" in the root of the project, and then, creating the files to run the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws-lambda-localstack
|test/
|- file/
|- - test_file.log
|- - input-event-test.json
|requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;test_file.log&lt;/strong&gt;: this file will be used as an example from the bucket. It could be just an empty file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;requirements.txt&lt;/strong&gt;: this file is required by "SAM CLI".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;input-event-test.json&lt;/strong&gt;: this one is the input test that will be called when running the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Records": [
    {
      "eventVersion": "2.0",
      "eventSource": "aws:s3",
      "awsRegion": "us-east-1",
      "eventTime": "1970-01-01T00:00:00.000Z",
      "eventName": "ObjectCreated:Put",
      "userIdentity": {
        "principalId": "EXAMPLE"
      },
      "requestParameters": {
        "sourceIPAddress": "127.0.0.1"
      },
      "responseElements": {
        "x-amz-request-id": "EXAMPLE123456789",
        "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
      },
      "s3": {
        "s3SchemaVersion": "1.0",
        "configurationId": "testConfigRule",
        "bucket": {
          "name": "tutorial",
          "ownerIdentity": {
            "principalId": "EXAMPLE"
          },
          "arn": "arn:aws:s3:::example-bucket"
        },
        "object": {
          "key": "lambda/test_file.log",
          "size": 1024,
          "eTag": "0123456789abcdef0123456789abcdef",
          "sequencer": "0A1B2C3D4E5F678901"
        }
      }
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Once the steps before are done, the next step will configure the "run configuration".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flcb6dynn23csq1v8np0m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flcb6dynn23csq1v8np0m.png" alt="image 03-pycharm-run-configuration" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd2sys59j4t20d07rk72t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd2sys59j4t20d07rk72t.png" alt="image-03-pycharm-run-configuration-aws-connection" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the IDE configuration is done, and then, let's configure the entries. For configuring the entries it's mandatory to run some commands to create the files on the S3 and to create the SQS Queue.&lt;/p&gt;

&lt;p&gt;1 - Creating the bucket on S3: the bucket will be named "tutorial".&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ aws --endpoint-url=http://localhost:4572 s3 mb s3://tutorial&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;2 -  Creating a folder on S3: it'll be creating a folder named "lambda".&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ aws --endpoint-url=http://localhost:4572 s3api put-object --bucket tutorial --key lambda&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;The response will be something like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\""
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 - Copying files to bucket: copying files from "./test/files" to "s3://tutorial/lambda/"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws --endpoint-url=http://localhost:4572 s3 cp ./test/files/ s3://tutorial/lambda/ --recursive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To check if the bucket was created, copy the value from "endpoint-url" and execute a "curl" or paste in the browser, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -v http://localhost:4572/tutorial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will be something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"&amp;gt;
   &amp;lt;Name&amp;gt;tutorial&amp;lt;/Name&amp;gt;
   &amp;lt;MaxKeys&amp;gt;1000&amp;lt;/MaxKeys&amp;gt;
   &amp;lt;Delimiter&amp;gt;None&amp;lt;/Delimiter&amp;gt;
   &amp;lt;IsTruncated&amp;gt;false&amp;lt;/IsTruncated&amp;gt;
   &amp;lt;Contents&amp;gt;
      &amp;lt;Key&amp;gt;lambda&amp;lt;/Key&amp;gt;
      &amp;lt;LastModified&amp;gt;2020-04-28T01:36:04.128Z&amp;lt;/LastModified&amp;gt;
      &amp;lt;ETag&amp;gt;"d41d8cd98f00b204e9800998ecf8427e"&amp;lt;/ETag&amp;gt;
      &amp;lt;Size&amp;gt;0&amp;lt;/Size&amp;gt;
      &amp;lt;StorageClass&amp;gt;STANDARD&amp;lt;/StorageClass&amp;gt;
      &amp;lt;Owner&amp;gt;
         &amp;lt;ID&amp;gt;75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a&amp;lt;/ID&amp;gt;
         &amp;lt;DisplayName&amp;gt;webfile&amp;lt;/DisplayName&amp;gt;
      &amp;lt;/Owner&amp;gt;
   &amp;lt;/Contents&amp;gt;
   &amp;lt;Contents&amp;gt;
      &amp;lt;Key&amp;gt;lambda/input-event-test.json&amp;lt;/Key&amp;gt;
      &amp;lt;LastModified&amp;gt;2020-04-28T01:40:27.882Z&amp;lt;/LastModified&amp;gt;
      &amp;lt;ETag&amp;gt;"4e114da7aa17878f62bf4485a90a97a2"&amp;lt;/ETag&amp;gt;
      &amp;lt;Size&amp;gt;1011&amp;lt;/Size&amp;gt;
      &amp;lt;StorageClass&amp;gt;STANDARD&amp;lt;/StorageClass&amp;gt;
      &amp;lt;Owner&amp;gt;
         &amp;lt;ID&amp;gt;75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a&amp;lt;/ID&amp;gt;
         &amp;lt;DisplayName&amp;gt;webfile&amp;lt;/DisplayName&amp;gt;
      &amp;lt;/Owner&amp;gt;
   &amp;lt;/Contents&amp;gt;
   &amp;lt;Contents&amp;gt;
      &amp;lt;Key&amp;gt;lambda/test_file.log&amp;lt;/Key&amp;gt;
      &amp;lt;LastModified&amp;gt;2020-04-28T01:40:27.883Z&amp;lt;/LastModified&amp;gt;
      &amp;lt;ETag&amp;gt;"4ac646c9537443757aff7ebd0df4f448"&amp;lt;/ETag&amp;gt;
      &amp;lt;Size&amp;gt;29&amp;lt;/Size&amp;gt;
      &amp;lt;StorageClass&amp;gt;STANDARD&amp;lt;/StorageClass&amp;gt;
      &amp;lt;Owner&amp;gt;
         &amp;lt;ID&amp;gt;75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a&amp;lt;/ID&amp;gt;
         &amp;lt;DisplayName&amp;gt;webfile&amp;lt;/DisplayName&amp;gt;
      &amp;lt;/Owner&amp;gt;
   &amp;lt;/Contents&amp;gt;
&amp;lt;/ListBucketResult&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4 - Creating an SQS Queue&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws --endpoint-url=http://localhost:4576 sqs create-queue --queue-name lambda-tutorial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exit will be somthing like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "QueueUrl": "http://localhost:4576/queue/lambda-tutorial"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once everything is done, and all output was okay, it's time to run the project. Note, in the code was written the input and the output for this text. And so, to run click in the "Run '[Local] lambda_function.lambda_handler'" button. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvxpjii26t2fzx0o8sv6x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvxpjii26t2fzx0o8sv6x.png" alt="image-04-pycharm-run-project" width="800" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After this, it's possible to see the output from this process on the console. It's showing the entries, and in the final ten messages are recovered from the queue and printed in the console.&lt;/p&gt;

&lt;p&gt;GREAT!&lt;/p&gt;

&lt;h2&gt;
  
  
  It's Done!
&lt;/h2&gt;

&lt;p&gt;This can be just the initial point, and I hope that this text helps you test your AWS services... I hope that all of you reach your goals.&lt;/p&gt;

&lt;p&gt;Repository: &lt;a href="https://bitbucket.org/MaironCosta/aws-lambda-localstack/src/master/"&gt;aws-lambda-localstack&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you for reading 'till the end! &lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;Some references that I have used to complete this text.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html"&gt;AWS SAM CLI&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html"&gt;AWS CLI&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://serverless.com/"&gt;Serverless&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/localstack/localstack"&gt;Localstack&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/manomano-tech/using-serverless-framework-localstack-to-test-your-aws-applications-locally-17748ffe6755"&gt;Using Serverless Framework &amp;amp; Localstack to test your AWS applications locally&lt;/a&gt;;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Some Cloud Computing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/"&gt;AWS&lt;/a&gt;; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://azure.microsoft.com/"&gt;Azure&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cloud.google.com/"&gt;GoogleCloud&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.openshift.com/"&gt;Openshift&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.oracle.com/cloud/"&gt;Oracle&lt;/a&gt;;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>lambda</category>
      <category>localstack</category>
      <category>serverless</category>
      <category>python</category>
    </item>
    <item>
      <title>Bitbucket-Pipeline: How to deploy a docker image to Heroku using Springboot</title>
      <dc:creator>Mairon Costa</dc:creator>
      <pubDate>Fri, 20 Dec 2019 20:13:29 +0000</pubDate>
      <link>https://dev.to/maironmscosta/bitbucket-pipeline-how-to-deploy-a-docker-image-to-heroku-using-springboot-4ldc</link>
      <guid>https://dev.to/maironmscosta/bitbucket-pipeline-how-to-deploy-a-docker-image-to-heroku-using-springboot-4ldc</guid>
      <description>&lt;p&gt;Hey, guys, how’s going!? Nowadays (2019-2020) the IT market has been growing, new technologies appeared, and, as tendencies, the CI - Continuous Integration -  and CD - Continuous Delivery (in some case Continuous Deploy).  &lt;/p&gt;

&lt;p&gt;The following text has as a goal to explain how to deploy a docker image on Heroku platform using Bitbucket, using the bitbucket-pipeline. This way, it’ll be done a deploy after a commit be done on Bitbucket. The text has an academic context and as a programming language was choice Java, using Springboot with maven. It’s important to inform that it depends on you getting better and/or change what’s been informed here to help or support you.&lt;/p&gt;

&lt;p&gt;Presume it here that for you came here the reader is a Bitbucket user, in this case, know use git, and, you know use Heroku. If you don’t know what is it, it’s recommended you search for both, as about the Bitbucket (&lt;a href="https://bitbucket.org/" rel="noopener noreferrer"&gt;https://bitbucket.org/&lt;/a&gt; , &lt;a href="https://pt.wikipedia.org/wiki/Bitbucket" rel="noopener noreferrer"&gt;https://pt.wikipedia.org/wiki/Bitbucket&lt;/a&gt;) as a Heroku  (&lt;a href="https://www.heroku.com/" rel="noopener noreferrer"&gt;https://www.heroku.com/&lt;/a&gt; , &lt;a href="https://en.wikipedia.org/wiki/Heroku" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Heroku&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;let’s go! &lt;/p&gt;

&lt;p&gt;To do this example the Intellij Community was used as IDE and the Ubuntu 18.04 LTS was used as the operational system.&lt;/p&gt;

&lt;p&gt;The project tree as like following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fu9t029vru4i0errz1xd0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fu9t029vru4i0errz1xd0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Look that exists the “bitbucket-pipeline.yml” file in the root project and this is fundamental to get success. However, this will be talked about and some other points as follows. &lt;/p&gt;

&lt;h3&gt;
  
  
  1. Heroku
&lt;/h3&gt;

&lt;p&gt;At this point, the Heroku configuration will be done. The application will be created, the environment variable will be added and the “API key” will be generated. &lt;/p&gt;

&lt;h4&gt;
  
  
  1.1 Creating the application on Heroku
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fank2iz5k9pxzn5hvtgh4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fank2iz5k9pxzn5hvtgh4.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  1.2 Adding the environment variable
&lt;/h4&gt;

&lt;p&gt;The reason to have the environment variable it's because it will be informed which “Profile” will be used to start the application on Heroku.  In this case, for example, it’s possible that you may want to have a test environment, or developer environment, or production environment and because of this, it’ll be passed this information through the environment variable.&lt;/p&gt;

&lt;p&gt;To add a environment variable is necessary that you go in the page of project created, in “Settings”, click in “Reveal Config Vars” and following inform the variables, that in this case, it will be informed as key “SPRING_PROFILE” and as value will be informed “heroku”, and after inform, you have to click on “Add” button. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fbm8nkzyufi9qc3yztpf6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fbm8nkzyufi9qc3yztpf6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  1.3 API Key
&lt;/h4&gt;

&lt;p&gt;At this moment you have to save the “API Key”. This key will make possible to do the deploy being out from Heroku platform. For this, you have to go in “Account settings” and following go to the field “API Key”, if the key doesn’t exist you must create it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fmu6gx2yznwikp0jw8usz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fmu6gx2yznwikp0jw8usz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. BitBucket
&lt;/h3&gt;

&lt;p&gt;At this step, the Bitbucket Pipeline will be turned on and the environment variable will be added.&lt;/p&gt;

&lt;h4&gt;
  
  
  2.1 Turn on Pipeline
&lt;/h4&gt;

&lt;p&gt;At the Bitbucket platform, the pipeline will be turned on and for such, it’s necessary to go to settings from the project, go to option “Pipeline &amp;gt; Settings” and turned on this option.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1jarirnta43l968rlnur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1jarirnta43l968rlnur.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2.2 Adding the environment variable
&lt;/h4&gt;

&lt;p&gt;In the next step, the environment variables will be added into the project and for such, you have to return to the project configuration and to go to “Pipeline &amp;gt; Repository variables”. The environment variables that will be added are “HEROKU_API_KEY”, this one was generated into the “API Key” step from Heroku and it’ll be added “HEROKU_APP_NAME” too, this one which is the application name created on Heroku.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0ko2d14bw7qy6vag54em.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0ko2d14bw7qy6vag54em.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Application
&lt;/h3&gt;

&lt;p&gt;It’s time to configure the application to it could be possible to run the pipeline when a commit on branch master will be done and this way the deploy could be done on Heroku.&lt;br&gt;
It’s important to say that Java with Springboot was chosen as the programming language, and the Intellij Community is used as IDE.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.1 Application.yml
&lt;/h4&gt;

&lt;p&gt;Now it’ll be created the “application.yml” file inside the “resource” folder from the project at the same level that the “application.properties”. Into this file will be informed of the profile name and the port that the application will start. Realize that there are two profiles, one is for development (dev profile) and another one in which the Heroku (heroku profile) will use to start the application. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#redis
#host: if you going to use docker you must change the host to work based on IP,
# its mean that you musn't use localhost or 127.0.0.1
#spring.redis.host=10.0.0.21
spring:
  application:
    name: bbpipeline-heroku-api

---
spring:
  profiles: dev
server:
  port: 8081

---
spring:
  profiles: heroku
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fluwwo7ygqqihmzpllj7h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fluwwo7ygqqihmzpllj7h.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3.2 Bitbucket-pipeline.yml
&lt;/h4&gt;

&lt;p&gt;In this point is necessary to create the “bitbucket-pipeline.yml” file into the root project, because this one has the formula that will be read and execute inside the Bitbucket.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# This is a sample build configuration for Java (Maven).
# Check our guides at https://confluence.atlassian.com/x/zd-5Mw for more examples.
# Only use spaces to indent your .yml configuration.
# -----
# You can specify a custom docker image from Docker Hub as your build environment.
image: maven:3.6.1

pipelines:
  branches:
    master:
      - step: #Its working
          name: Create Artifact
          caches:
            - maven
          script: # Modify the commands below to build your repository.
            - mvn -B package # -B batch mode makes Maven less verbose
          artifacts: # defining the artifacts to be passed to each future step.
            - target/**

      - step:
          name: Push docker image to the Heroku
          deployment: Production
          services:
            - docker
          script:
            - curl https://cli-assets.heroku.com/install-ubuntu.sh | sh
            - heroku container:login
            - heroku container:push web -a $HEROKU_APP_NAME
            - heroku container:release web -a $HEROKU_APP_NAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fy11jibzpaxrh8h9o34gl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fy11jibzpaxrh8h9o34gl.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pay attention that there is “branch: master:”, in this case, the pipeline will be executed every single time that a commit will be done on branch master and inside this hierarchy, there are the steps, this steps that will be executed by script after the commit on branch master be done.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Into step named by “Create Artifact” will be executed the “mvn -B package” command (if there are tests they will be executed) and following it’ll be created for a short time a folder named by “target”, this folder contains the files that will be used on application create on docker container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Into step called by “Push docker image to the Heroku” will be used “services’ from docker to create the image and the following will be executed the script. Into script, the first step is to install the “heroku standalone” (command used to install: curl &lt;a href="https://cli-assets.heroku.com/install-ubuntu.sh" rel="noopener noreferrer"&gt;https://cli-assets.heroku.com/install-ubuntu.sh&lt;/a&gt; | sh); after to do log in on Heroku system and in this moment it will be using the “API Key” (this one that was put as environment variable) as access key to the Heroku; and as follow the docker image created will be sent and the deploy will be done. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3.3 Dockerfile
&lt;/h4&gt;

&lt;p&gt;At this step will be created the file that will be used to create the docker image. The Dockerfile has to be created into the root project and it doesn’t must to contain an extension, in other words, nothing like “Dockerfile.txt”, “Dockerfile.yml”, “Dockerfile.doc” or “Dockerfile.sh”.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# https://spring.io/guides/gs/spring-boot-docker/
#FROM openjdk:11
FROM adoptopenjdk/openjdk11:latest
VOLUME /tmp

ARG DEPENDENCY_CLASS=target/dependency
COPY ${DEPENDENCY_CLASS}/BOOT-INF/lib        /app/lib
COPY ${DEPENDENCY_CLASS}/META-INF            /app/META-INF
COPY ${DEPENDENCY_CLASS}/BOOT-INF/classes    /app

CMD ["java","-Dspring.profiles.active=${SPRING_PROFILE}","-cp","app:app/lib/*","com.bbpipeline.BBPipelineApplication"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fhieu54qib82ci7tp2hxh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fhieu54qib82ci7tp2hxh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Realize that the “target/dependency” folder is used into Dockerfile, because of this folder that into “bitbucket-pipeline.yml” is created the artifact “target/**” and has the “SPRING_PROFILE” as environment variable too, this variable that was informed as an environment variable on Heroku.&lt;/p&gt;

&lt;p&gt;Look that, into the command line used to start the application into docker is used the “CMD”, this one is used because of Heroku can inform the environment variable, because if it was with “ENTRYPOINT” this doesn’t work.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.4 Application.properties
&lt;/h4&gt;

&lt;p&gt;Into the “application.properties” will be added to the line “server.port=${PORT}”, this line allows that when the application starts the Heroku could inform what port the application will run. If the application is with the developer it will be used the profile “dev”, this line will be ignored and the port will be informed by the respective profile describe into “application.yml”.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring.profiles.active=dev
# Server port
server.port=${PORT}

#logging
logging.level.org.springframework.data=debug
logging.level.=error

spring.main.allow-bean-definition-overriding=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fhyf17cd8xuw31g9sn4vp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fhyf17cd8xuw31g9sn4vp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After executing these steps, the application will start on Heroku and it will be possible to check into the log that the application started with the heroku profile.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7vrq5l3wlxhmlpns789v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7vrq5l3wlxhmlpns789v.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s could say that the process flow is simple, basically, there is an entrance that is a commit, there is processing that will run inside on Bitbucket and an out that will be the deploy the docker image on Heroku.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fc96quca1fn6vug05b0am.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fc96quca1fn6vug05b0am.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project repository on Bitbucket:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;git clone &lt;a href="https://MaironCosta@bitbucket.org/maironpublic/test-bitbucket-pipeline-heroku.git" rel="noopener noreferrer"&gt;https://MaironCosta@bitbucket.org/maironpublic/test-bitbucket-pipeline-heroku.git&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;git clone &lt;a href="mailto:git@bitbucket.org"&gt;git@bitbucket.org&lt;/a&gt;:maironpublic/test-bitbucket-pipeline-heroku.git&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for following until the final and I hope that this can help you!&lt;/p&gt;

</description>
      <category>bitbucketpipeline</category>
      <category>docker</category>
      <category>devops</category>
      <category>continuosdelivery</category>
    </item>
  </channel>
</rss>
