<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Andrew Holovko</title><generator>teletype.in</generator><description><![CDATA[Blog of a self-taught programmer writing about the experience, tips and other stuff]]></description><image><url>https://img3.teletype.in/files/63/2a/632a938b-aa35-48ed-9baf-51dc6330d150.jpeg</url><title>Andrew Holovko</title><link>https://teletype.in/@andrewholovko</link></image><link>https://teletype.in/@andrewholovko?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/andrewholovko?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/andrewholovko?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Sun, 05 Apr 2026 09:19:07 GMT</pubDate><lastBuildDate>Sun, 05 Apr 2026 09:19:07 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@andrewholovko/save-all-optimization</guid><link>https://teletype.in/@andrewholovko/save-all-optimization?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko</link><comments>https://teletype.in/@andrewholovko/save-all-optimization?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko#comments</comments><dc:creator>andrewholovko</dc:creator><title>Optimizing repository.saveAll() JPA Hibernate</title><pubDate>Fri, 14 Mar 2025 13:24:10 GMT</pubDate><description><![CDATA[Problem. Invoking repository.saveAll() has to insert into DB by batches, but it doesn't.]]></description><content:encoded><![CDATA[
  <p id="2U4s"><strong>Problem</strong>. Invoking <em><code>repository.saveAll(</code>)</em> has to insert into DB by batches, but it doesn&#x27;t.</p>
  <p id="cGE1"><strong>Result of the investigation</strong>.<br />Current realisation inserts new records one by one. Batching doesn&#x27;t work because of <code>IDENTITY</code> id generator.</p>
  <p id="kcf1">Hibernate batch processing works only with <code>SEQUENCE</code> id generator. And with properties:<br /><code>spring.jpa.properties.hibernate.jdbc.batch_size=30<br />spring.jpa.properties.hibernate.order_inserts=true</code></p>
  <p id="F3gN">Links: <a href="https://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch15.html" target="_blank">https://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch15.html</a></p>
  <p id="G3mq"><strong>Solution</strong>:<br />Move to <code>SEQUENCE</code> id generator.<br />Create the <code>my_table_id_seq</code> for table <code>my_table</code>. Or create new in case there is not exist.<br />Then restart it from the latest existing primary key.</p>
  <p id="zOuw"><code>SELECT SETVAL(&#x27;my_table_id_seq&#x27;, (SELECT MAX(id) + 1 FROM my_table));</code></p>
  <p id="JlL0"><strong>Test 1</strong>: <strong>saving of 50_000 records took 20 seconds</strong>.<br />Set up with identity generator: <br /><strong>1)</strong> MyEntity<br />  <code>@Id<br />  @GeneratedValue(strategy = GenerationType.IDENTITY)<br />  @Column(name = &quot;id&quot;)<br />  private Long id;</code></p>
  <p id="yzw9"><strong>2)</strong> properties.yaml<br /><code>spring.jpa.properties.hibernate.jdbc.batch_size=30<br />spring.jpa.properties.hibernate.order_inserts=true</code></p>
  <p id="jXse"><em>In the log you can see that batchSize = 0. There is 50_000 logs entries. Batching doesn&#x27;t work.</em></p>
  <p id="34dr">Log:</p>
  <p id="uja7"><em>{&quot;name&quot;:&quot;Batch-Insert-Logger&quot;, &quot;connection&quot;:5, &quot;time&quot;:0, &quot;success&quot;:true, &quot;type&quot;:&quot;Prepared&quot;, &quot;batch&quot;:false, &quot;querySize&quot;:1, &quot;batchSize&quot;:0, &quot;query&quot;:[&quot;insert into my_table (created,id,full_name,updated) values (?,?,?,?,)&quot;], &quot;params&quot;:[[&quot;2025-03-06 12:07:07.010665&quot;,&quot;698606&quot;,&quot;John Doe&quot;,&quot;2025-03-06 12:07:07.010666&quot;]]}</em></p>
  <p id="4agm"><strong>Test 2: saving of 50_000 records took 6 seconds.</strong><br />Set up with sequence generator: <br /><strong>1)</strong> MyEntity<br />  <code>@Id<br />  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = &quot;mySeqGen&quot;)<br />  @SequenceGenerator(name = &quot;mySeqGen&quot;, sequenceName = &quot;my_table_id_seq&quot;, allocationSize = 1)<br />  @Column(name = &quot;id&quot;)<br />  private Long id;</code></p>
  <p id="Fjsx"><strong>2) </strong>properties.yaml<br /><code>spring.jpa.properties.hibernate.jdbc.batch_size=30<br />spring.jpa.properties.hibernate.order_inserts=true</code></p>
  <p id="WM8c"><em>In the log you can see that batchSize = 30. There is 117 logs entries with batch size = 30 and 1 log entry with batch size = 20. Batching works.</em></p>
  <p id="bwN0">Log:</p>
  <p id="0iMm"><em>{&quot;name&quot;:&quot;Batch-Insert-Logger&quot;, &quot;connection&quot;:5, &quot;time&quot;:0, &quot;success&quot;:true, &quot;type&quot;:&quot;Prepared&quot;, &quot;batch&quot;:true, &quot;querySize&quot;:1, &quot;batchSize&quot;:30, &quot;query&quot;:[&quot;insert into my_table (created,id,full_name,updated) values (?,?,?,?)&quot;], &quot;params&quot;: []}</em></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@andrewholovko/PB-uYqrJsKP</guid><link>https://teletype.in/@andrewholovko/PB-uYqrJsKP?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko</link><comments>https://teletype.in/@andrewholovko/PB-uYqrJsKP?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko#comments</comments><dc:creator>andrewholovko</dc:creator><title>CodingBat: DividesSelf</title><pubDate>Sat, 01 Mar 2025 19:32:03 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/1d/0f/1d0f34d5-aad2-4080-bf20-07a89ffc9d01.png"></media:content><description><![CDATA[<img src="https://img3.teletype.in/files/ad/45/ad459e0b-4bfa-4189-8aee-8b4c9f2568b1.png"></img>Task:]]></description><content:encoded><![CDATA[
  <p id="Pz9B"><strong>Task</strong>:</p>
  <p id="om4D">We&#x27;ll say that a positive int divides itself if every digit in the number divides into the number evenly. So for example 128 divides itself since 1, 2, and 8 all divide into 128 evenly. We&#x27;ll say that 0 does not divide into anything evenly, so no number with a 0 digit divides itself. Note: use % to get the rightmost digit, and / to discard the rightmost digit.</p>
  <p id="llCw"><strong>Example</strong>:<br />dividesSelf(128) → true<br />dividesSelf(12) → true<br />dividesSelf(120) → false</p>
  <p id="u9uK"></p>
  <figure id="NEJ7" class="m_retina">
    <img src="https://img3.teletype.in/files/ad/45/ad459e0b-4bfa-4189-8aee-8b4c9f2568b1.png" width="633" />
  </figure>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@andrewholovko/69dp7afiBmC</guid><link>https://teletype.in/@andrewholovko/69dp7afiBmC?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko</link><comments>https://teletype.in/@andrewholovko/69dp7afiBmC?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko#comments</comments><dc:creator>andrewholovko</dc:creator><title>Solver: pangram problem</title><pubDate>Mon, 10 Feb 2025 20:41:33 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/09/f0/09f0cab4-1214-4578-8082-959124391181.png"></media:content><category>Interview</category><description><![CDATA[<img src="https://img1.teletype.in/files/c9/ce/c9ce36f5-457d-4a2c-a1ba-26297666f4f9.png"></img>A pangram is a string that contains every letter of the alphabet. Given a sentence determine whether it is a pangram in the English alphabet. Ignore case. Return either pangram or not pangram as appropriate.]]></description><content:encoded><![CDATA[
  <figure id="J4MK" class="m_column">
    <img src="https://img1.teletype.in/files/c9/ce/c9ce36f5-457d-4a2c-a1ba-26297666f4f9.png" width="1024" />
  </figure>
  <p id="v7qg">A <em>pangram</em> is a string that contains every letter of the alphabet. Given a sentence determine whether it is a pangram in the English alphabet. Ignore case. Return either <code>pangram</code> or <code>not pangram</code> as appropriate.</p>
  <p id="GY8c"><strong>Example: The quick brown fox jumps over the lazy dog</strong></p>
  <p id="t44W">The string contains all letters in the English alphabet, so return <code>pangram</code>.</p>
  <p id="yHt5"></p>
  <figure id="E0YR" class="m_column">
    <img src="https://img4.teletype.in/files/b8/f4/b8f486a9-af9d-4b08-a71c-aa83d955aa19.png" width="876" />
  </figure>
  <figure id="L6zi" class="m_column">
    <img src="https://img1.teletype.in/files/89/b3/89b3851d-38b6-4bdd-9524-9612c67cfbe7.png" width="1340" />
    <figcaption>Tests</figcaption>
  </figure>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@andrewholovko/vo1_IwF1XtJ</guid><link>https://teletype.in/@andrewholovko/vo1_IwF1XtJ?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko</link><comments>https://teletype.in/@andrewholovko/vo1_IwF1XtJ?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko#comments</comments><dc:creator>andrewholovko</dc:creator><title>Concurrent Bank Transaction System in Java</title><pubDate>Sun, 09 Feb 2025 20:49:58 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/4d/4a/4d4ab700-11bd-4c3a-877e-df1777c6eb5b.png"></media:content><category>Java</category><description><![CDATA[<img src="https://img1.teletype.in/files/86/bf/86bf5324-2012-4cd7-9c5a-bd66ffe01d8d.png"></img>Below is an example of a concurrent bank transaction system in Java. In this example, we model a bank account with methods for deposit, withdrawal, and a transfer operation that involves two accounts. We use a ReentrantLock in each account to ensure that modifications to the account balance are thread-safe, and we take care to avoid deadlocks when transferring funds between two accounts.]]></description><content:encoded><![CDATA[
  <figure id="Wusr" class="m_column">
    <img src="https://img1.teletype.in/files/86/bf/86bf5324-2012-4cd7-9c5a-bd66ffe01d8d.png" width="1024" />
  </figure>
  <p id="Uebf">Below is an example of a concurrent bank transaction system in Java. In this example, we model a bank account with methods for deposit, withdrawal, and a transfer operation that involves two accounts. We use a <code>ReentrantLock</code> in each account to ensure that modifications to the account balance are thread-safe, and we take care to avoid deadlocks when transferring funds between two accounts.</p>
  <p id="f8O2"></p>
  <figure id="zgF6" class="m_retina">
    <img src="https://img4.teletype.in/files/35/9f/359febca-1873-4e9d-aaad-067163cf76e8.png" width="564" />
  </figure>
  <p id="vK2q"><strong>BankAccount Class:</strong></p>
  <ul id="3eQ6">
    <li id="55F8"><strong>Fields &amp; Lock:</strong><br />Each account has a unique <code>id</code>, a <code>balance</code>, and a dedicated <code>ReentrantLock</code> to protect its state.</li>
    <li id="Pm5Z"><strong>Deposit &amp; Withdraw:</strong><br />The methods <code>deposit()</code> and <code>withdraw()</code> lock the account before modifying the balance to ensure thread safety.</li>
    <li id="FKqS"><strong>Transfer Method:</strong><br />The static <code>transfer()</code> method transfers funds between two accounts.</li>
    <ul id="0tYB">
      <li id="GJBc">To prevent deadlocks when acquiring two locks (one for each account), we always lock the accounts in a fixed order based on their IDs.</li>
      <li id="Lu0A">Once both locks are acquired, the method checks for sufficient funds, performs the transfer, and then unlocks both accounts.</li>
    </ul>
  </ul>
  <figure id="pPUX" class="m_retina">
    <img src="https://img4.teletype.in/files/36/d6/36d6eab6-8d53-4843-b12c-8fcd7b1b65d1.png" width="817" />
  </figure>
  <figure id="MuJs" class="m_retina">
    <img src="https://img4.teletype.in/files/36/d6/36d6eab6-8d53-4843-b12c-8fcd7b1b65d1.png" width="817" />
  </figure>
  <figure id="f1jq" class="m_retina">
    <img src="https://img1.teletype.in/files/4a/56/4a5682b9-642c-4a19-b83e-ac4958331c41.png" width="647" />
  </figure>
  <p id="vfsk"><strong>(Main Simulation):</strong></p>
  <ol id="kz6I">
    <ul id="BVbn">
      <li id="hHGa"><strong>ExecutorService:</strong><br />We use a fixed thread pool to simulate concurrent transactions.</li>
      <li id="jALE"><strong>Tasks:</strong><br />Three tasks are created to transfer funds between the accounts:</li>
      <ul id="yAUD">
        <li id="kIch">Task 1 transfers money from Account 1 to Account 2.</li>
        <li id="WtAb">Task 2 transfers money from Account 2 to Account 1.</li>
      </ul>
    </ul>
    <ul id="IbVV">
      <li id="22c4"><strong>Shutdown &amp; Final Output:</strong><br />The executor is shut down gracefully after submitting the tasks, and once all tasks complete, the final balances of each account are printed.</li>
    </ul>
  </ol>
  <p id="4gW7">This example demonstrates key concurrency concepts in a real-world banking scenario, including proper synchronization with locks, avoiding deadlock by enforcing a lock order, and managing concurrent tasks using an <code>ExecutorService</code>.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@andrewholovko/kafkajs-nestjs-prometheus</guid><link>https://teletype.in/@andrewholovko/kafkajs-nestjs-prometheus?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko</link><comments>https://teletype.in/@andrewholovko/kafkajs-nestjs-prometheus?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko#comments</comments><dc:creator>andrewholovko</dc:creator><title>How to integrate kafka-prometheus-exporter and NestJs prometheus module</title><pubDate>Mon, 27 Jan 2025 16:38:48 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/7d/65/7d65ec24-5eeb-4dc2-82b7-d42f3ae7af21.png"></media:content><description><![CDATA[<img src="https://img3.teletype.in/files/2a/d7/2ad7a9d7-b963-4c31-af96-17c852759c7b.png"></img>Monitoring applications is crucial for understanding their performance, availability, and health. In this article, we’ll walk through setting up monitoring for a NestJS application using Prometheus.]]></description><content:encoded><![CDATA[
  <p id="EkVs">Monitoring applications is crucial for understanding their performance, availability, and health. In this article, we’ll walk through setting up monitoring for a NestJS application using Prometheus.</p>
  <p id="UIHb">There are a lot of guides about setting up Prometheus module in NestJS application and several guides about usage kafka-prometheus-exporter library. The last one is not wideused for unknown reason for me. But there is no instructrusctions how to set up both.</p>
  <p id="tcZg">Firstly, let’s intall and setup Prometheus module</p>
  <p id="pmEL">npm install @willsoto/nestjs-prometheus prom-client</p>
  <p id="21dR"><code>import { Module } from &quot;@nestjs/common&quot;;</code></p>
  <p id="4ZBJ"><code>import { PrometheusModule } from &quot;@willsoto/nestjs-prometheus&quot;;</code></p>
  <p id="dYf1"><code>@Module({</code></p>
  <p id="1dRX"><code>imports: [PrometheusModule.register()],</code></p>
  <p id="YLcp"><code>})</code></p>
  <p id="nyZK"><code>export class AppModule {}</code></p>
  <p id="DRg7">At this stage you can run your application and visit localhost:3000/metrics to see default metrics.</p>
  <p id="t85K">The below snippet shows kafka client configuration and provides util methods for monitoring.</p>
  <p id="uZFb">You don’t need to create new Registry() as it mentions in other guides. Just retrieve the existing ones and pass it to kafkajs-prometheus-exporter functions.</p>
  <p id="yww3"><code>// kafka.config.ts</code></p>
  <p id="g1Yt"><code>import {Consumer, Kafka, Producer} from &#x27;kafkajs&#x27;;</code></p>
  <p id="rhMF"><code>import {Injectable} from &#x27;@nestjs/common&#x27;;</code></p>
  <p id="wfWz"><code>import {ConfigService} from &#x27;@nestjs/config&#x27;;</code></p>
  <p id="XDzU"><code>import * as fs from &#x27;fs&#x27;;</code></p>
  <p id="3WkJ"><code>import {</code></p>
  <p id="eFpL"><code>monitorKafkaJSAdmin,</code></p>
  <p id="8fBt"><code>monitorKafkaJSConsumer,</code></p>
  <p id="5U7c"><code>monitorKafkaJSProducer</code></p>
  <p id="filS"><code>} from &#x27;@christiangalsterer/kafkajs-prometheus-exporter&#x27;;</code></p>
  <p id="ORBl"><code>import {Registry} from &#x27;prom-client&#x27;;</code></p>
  <p id="bItE"><code>import * as promClient from &#x27;prom-client&#x27;;</code></p>
  <p id="dSt9"><code>@Injectable()</code></p>
  <p id="lDQq"><code>export class KafkaConfig {</code></p>
  <p id="bBCQ"><code>private readonly _kafkaConfig: Kafka;</code></p>
  <p id="R6c2"><code>private readonly registry: Registry;</code></p>
  <p id="ASlN"><code>constructor(private readonly configService: ConfigService) {</code></p>
  <p id="FgL4"><code>this.registry = promClient.register</code></p>
  <p id="9ypI"><code>this._kafkaConfig = new Kafka({</code></p>
  <p id="dSxz"><code>brokers: configService.get(&#x27;KAFKA_BROKER&#x27;),</code></p>
  <p id="cqbl"><code>clientId: configService.get(&#x27;KAFKA_CLIENT_ID&#x27;),</code></p>
  <p id="UKsN"><code>});</code></p>
  <p id="liZ1"><code>let admin = this._kafkaConfig.admin();</code></p>
  <p id="Fb4k"><code>monitorKafkaJSAdmin(admin, this.registry);</code></p>
  <p id="fPzC"><code>admin.connect().then(() =&gt; {console.log(&#x27;Kafka admin connected&#x27;);});</code></p>
  <p id="VurK"><code>}</code></p>
  <p id="ic6A"><code>getConfig(): Kafka {</code></p>
  <p id="MJOM"><code>return this._kafkaConfig;</code></p>
  <p id="HXiF"><code>}</code></p>
  <p id="rOpL"><code>monitorConsumer(consumer: Consumer): void {</code></p>
  <p id="GjCD"><code>monitorKafkaJSConsumer(consumer, this.registry, { defaultLabels: {client_id: this.configService.get(&#x27;KAFKA_CLIENT_ID&#x27;)} });</code></p>
  <p id="3elq"><code>}</code></p>
  <p id="FxfF"><code>monitorProducer(producer: Producer): void {</code></p>
  <p id="gSu6"><code>monitorKafkaJSProducer(producer, this.registry, { defaultLabels: {client_id: this.configService.get(&#x27;KAFKA_CLIENT_ID&#x27;)} });</code></p>
  <p id="z2lD"><code>}</code></p>
  <p id="eaWV"><code>}</code></p>
  <p id="gCaV">Below you can find short snippets of usage. Be aware connect() should be called after registering the metrics.</p>
  <p id="cm84"><code>// create producer</code></p>
  <p id="woR0"><code>this.kafka = kafkaConfig.getConfig();</code></p>
  <p id="dOgR"><code>this.producer = this.kafka.producer();</code></p>
  <p id="OreB"><code>// monitor before connect()</code></p>
  <p id="MlK7"><code>kafkaConfigService.monitorProducer(this.producer);</code></p>
  <p id="QEY1"><code>await this.producer.connect();</code></p>
  <p id="kdSk"><code>// create consumer</code></p>
  <p id="AD3l"><code>this.kafka = kafkaConfigService.getConfig();</code></p>
  <p id="C8Y1"><code>this.consumer = this.kafka.consumer(config);</code></p>
  <p id="I5rO"><code>// monitor before connect()</code></p>
  <p id="bVUx"><code>kafkaConfigService.monitorConsumer(this.consumer);</code></p>
  <p id="ZzXw"><code>await this.consumer.connect();</code></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@andrewholovko/XtvPkDkt4hU</guid><link>https://teletype.in/@andrewholovko/XtvPkDkt4hU?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko</link><comments>https://teletype.in/@andrewholovko/XtvPkDkt4hU?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko#comments</comments><dc:creator>andrewholovko</dc:creator><title>M04 Q44 When do you want use @DataJpaTest for? What does it auto-configure?</title><pubDate>Sat, 11 Sep 2021 11:29:10 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/50/29/50291cc9-51b6-4848-9831-5d03869d879b.png"></media:content><category>Spting Boot Testing</category><description><![CDATA[<img src="https://img1.teletype.in/files/08/24/0824dfdd-804f-4b4c-87f0-5bc55a4b4387.png"></img>You want to use @DataJpaTest annotation whenever writing an Integration Test for JPA related components of your application like Entities or Repositories.]]></description><content:encoded><![CDATA[
  <figure id="RZ3v" class="m_column">
    <img src="https://img1.teletype.in/files/08/24/0824dfdd-804f-4b4c-87f0-5bc55a4b4387.png" width="758" />
  </figure>
  <p id="NBrK">You want to use <code>@DataJpaTest</code> annotation whenever writing an Integration Test for JPA related components of your application like <code>Entities</code> or <code>Repositories</code>.</p>
  <p id="YkKJ"><code>@DataJpaTest</code> annotation configures:</p>
  <ul id="DTOE">
    <li id="tIB5">In-memory embedded database – behavior can be disabled with <code>@AutoConfigureTestDatabase(replace = Replace.NONE)</code></li>
    <li id="Xp0H">Scans and configures <code>@Entity</code> beans</li>
    <li id="k3za">Scans and configures Spring Data Repositories</li>
    <li id="vW0F">Configures <code>TestEntityManager</code></li>
    <li id="yXZ2"><strong>Does not load</strong> other components like <code>@Component</code>, <code>@Service</code>, <code>@Controller</code> etc.</li>
  </ul>
  <p id="ZGoL">Every <code>@DataJpaTest</code> is <strong>transactional by default</strong>, after each test transaction is rolled back. You can use <code>@Transactional</code> annotation to customize this behavior.</p>
  <p id="D4o1">When using <code>@DataJpaTest</code> you can access <code>TestEntityManager</code>, which contains subset of <code>EntityManager</code> methods that are useful for testing.</p>
  <figure id="EihP" class="m_original">
    <img src="https://img1.teletype.in/files/cf/0a/cf0aa720-f9ee-44e1-9c8a-da093d0ed384.png" width="766" />
  </figure>
  <figure id="uRAe" class="m_original">
    <img src="https://img1.teletype.in/files/47/1f/471ff48a-6bc7-4c89-b1ec-e6ac60b48b32.png" width="761" />
  </figure>
  <figure id="8DXQ" class="m_original">
    <img src="https://img2.teletype.in/files/d2/19/d2190648-4f51-4c72-ab09-a38b3079fb35.png" width="710" />
  </figure>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@andrewholovko/OPF8Z3lH2SC</guid><link>https://teletype.in/@andrewholovko/OPF8Z3lH2SC?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko</link><comments>https://teletype.in/@andrewholovko/OPF8Z3lH2SC?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko#comments</comments><dc:creator>andrewholovko</dc:creator><title>M04 Q43 What are the differences between @MockBean and @Mock?</title><pubDate>Sat, 11 Sep 2021 11:20:46 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/e7/55/e7555903-fda3-4a22-a2a8-906df87a44ea.png"></media:content><category>Spting Boot Testing</category><description><![CDATA[<img src="https://img4.teletype.in/files/76/58/7658de60-490c-406e-809f-0c22b9197266.png"></img>@Mock annotation comes from Mockito Framework which allows for easy Mock creation. This annotation is used by MockitoJUnitRunner, each field annotated with it will have Mock for specified class created. This annotation does not inject mocks into tested class on itself, to use injection you need to have target class annotated with @InjectMocks annotation.]]></description><content:encoded><![CDATA[
  <figure id="y6bb" class="m_column">
    <img src="https://img4.teletype.in/files/76/58/7658de60-490c-406e-809f-0c22b9197266.png" width="775" />
  </figure>
  <p id="WOB0"><code>@Mock</code> annotation comes from Mockito Framework which allows for easy Mock creation. This annotation is used by <code>MockitoJUnitRunner</code>, each field annotated with it will have Mock for specified class created. This annotation does not inject mocks into tested class on itself, to use injection you need to have target class annotated with <code>@InjectMocks</code> annotation.</p>
  <figure id="wYgU" class="m_original">
    <img src="https://img3.teletype.in/files/2c/b9/2cb992ec-d941-4f97-8ed2-8e22a367ea8f.png" width="532" />
  </figure>
  <figure id="5XWA" class="m_original">
    <img src="https://img2.teletype.in/files/d5/96/d596eb19-c6fa-4666-ab66-efde54c060a8.png" width="565" />
  </figure>
  <p id="WAXa"><code>@MockBean</code> annotation comes from <code>spring-boot-test</code>, it creates Mockito Mock and also injects it into Application Context created by <code>@SpringBootTest</code>. All beans which refers to mocked class via <code>@Autowired</code> will get this mock injected instead of real class.</p>
  <figure id="sbGZ" class="m_original">
    <img src="https://img2.teletype.in/files/d2/7d/d27da075-14db-4dce-92d3-92e8c86ff736.png" width="581" />
  </figure>
  <p id="nfTl">Main difference between <code>@MockBean</code> and <code>@Mock</code> annotation is that <code>@MockBean</code> creates mock and <strong>injects it into Application Context</strong>, while <code>@Mock</code> annotation only <strong>creates it</strong>, if you want to inject it, you can do it manually or with <code>@InjectMocks</code> annotation, however injection is being done to the class <strong>not whole Application Context</strong>.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@andrewholovko/A8-KW6go4zl</guid><link>https://teletype.in/@andrewholovko/A8-KW6go4zl?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko</link><comments>https://teletype.in/@andrewholovko/A8-KW6go4zl?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko#comments</comments><dc:creator>andrewholovko</dc:creator><title>M04 Q42 When do you want to use @WebMvcTest? What does it auto-configure?</title><pubDate>Sat, 11 Sep 2021 10:46:50 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/b6/7b/b67baf54-5118-465c-a8af-1efde32602f9.png"></media:content><category>Spting Boot Testing</category><description><![CDATA[<img src="https://img4.teletype.in/files/7e/6b/7e6b93a4-af7b-4415-a2de-8da8d7272925.png"></img>You should use @WebMvcTest annotation when you want to write Integration Test that is focused on web layer of your application. @WebMvcTest approach will create ApplicationContext that contains only web components and omits any other components that are not part of web layer. Other components, if required for the test, can be mocked with usage of @MockBean annotation or delivered by @Configuration annotated class imported with usage of @Import annotation.]]></description><content:encoded><![CDATA[
  <figure id="bITl" class="m_column">
    <img src="https://img4.teletype.in/files/7e/6b/7e6b93a4-af7b-4415-a2de-8da8d7272925.png" width="823" />
  </figure>
  <p id="1270">You should use <code>@WebMvcTest</code> annotation when you want to write Integration Test that is focused on web layer of your application. <code>@WebMvcTest</code> approach will create <code>ApplicationContext</code> that contains only web components and omits any other components that are not part of web layer. Other components, if required for the test, can be mocked with usage of <code>@MockBean</code> annotation or delivered by <code>@Configuration</code> annotated class imported with usage of <code>@Import</code> annotation.</p>
  <p id="8T8u"><code>@WebMvcTest</code> supports two cases:</p>
  <ol id="9F2M">
    <li id="NoSD">Single Controller Auto-Configuration – annotate test by providing Controller class - <code>@WebMvcTest(CityController.class)</code></li>
  </ol>
  <figure id="adAz" class="m_original">
    <img src="https://img2.teletype.in/files/5e/dc/5edc47e3-aecf-4dda-8b3b-6eacab5cfb49.png" width="391" />
  </figure>
  <ol id="kyOz">
    <li id="qr24">Multiple (All found) Controllers Auto-Configuration – just annotate test with <code>@WebMvcTest</code></li>
  </ol>
  <figure id="cZtQ" class="m_original">
    <img src="https://img2.teletype.in/files/52/4a/524a192d-3c9c-4fea-9ce8-9dec61452ece.png" width="408" />
  </figure>
  <p id="7UHK"><code>@WebMvcTest</code> annotation will auto-configure:</p>
  <ul id="O9gi">
    <li id="gxzW">Mock Mvc</li>
    <li id="MQ3P"><code>@Controller</code> annotated class</li>
    <li id="tJwD"><code>@ControllerAdvice</code> annotated class</li>
    <li id="SKqH"><code>@JsonComponent</code> annotated class</li>
    <li id="LCvM"><code>@Converter</code> annotated class</li>
    <li id="TxBY"><code>@GenericConverter</code> annotated class</li>
    <li id="lMEP"><code>@Filter</code> annotated class</li>
    <li id="iZa7"><code>@WebMvcConfigurer</code> annotated class</li>
    <li id="G8Al"><code>@HandlerMethodArgumentResolver</code> annotated class</li>
  </ul>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@andrewholovko/PSuq-OlqFG7</guid><link>https://teletype.in/@andrewholovko/PSuq-OlqFG7?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko</link><comments>https://teletype.in/@andrewholovko/PSuq-OlqFG7?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko#comments</comments><dc:creator>andrewholovko</dc:creator><title>M04 Q41 How do you perform integration testing with @SpringBootTest for a web application?</title><pubDate>Sat, 11 Sep 2021 10:38:10 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/2a/c1/2ac1d201-722a-4e68-843d-8b2d45b0dbfe.png"></media:content><category>Spting Boot Testing</category><description><![CDATA[<img src="https://img4.teletype.in/files/b4/57/b4574aca-ef7c-4804-8b34-b405e4f02f7e.png"></img>Integration Test by definition, should check interactions between few components of the system (at least two real, not-mocked components) to check if those components are delivering expected functionalities when working together. In each case when writing Integration Test you should decide how many components should interact in the test for it to be meaningful. Usually, you should decide on smallest possible amount of components that are enough to test specific functionality. Components that are not meaningful can be omitted, or mocked with usage of @MockBean annotation.]]></description><content:encoded><![CDATA[
  <figure id="w7RT" class="m_column">
    <img src="https://img4.teletype.in/files/b4/57/b4574aca-ef7c-4804-8b34-b405e4f02f7e.png" width="784" />
  </figure>
  <p id="nE5Q"><strong>Integration Test</strong> by definition, should check interactions between few components of the system <strong>(at least two real, not-mocked components)</strong> to check if those components are delivering expected functionalities when working together. In each case when writing Integration Test you should decide how many components should interact in the test for it to be meaningful. Usually, you should decide on smallest possible amount of components that are enough to test specific functionality. Components that are not meaningful can be omitted, or mocked with usage of <code>@MockBean</code> annotation.</p>
  <p id="01rC">Web components tests (Controller Tests, Rest Controller Tests), if tested in Integration way, should be written in a way for test to make a HTTP Request and check HTTP Response. This kind of approach results in meaningful test, which delivers feedback that actually checks if component works correctly.</p>
  <p id="BnRv">Spring Boot allows you to write Integration Tests for Web Components in two ways:</p>
  <figure id="QGlx" class="m_original">
    <img src="https://img4.teletype.in/files/7e/90/7e90f246-9fc7-4414-9058-73c3da4bfcc8.png" width="1333" />
  </figure>
  <figure id="bBr7" class="m_original">
    <img src="https://img4.teletype.in/files/b0/48/b048e910-6d5b-45a4-81c4-2d4be13d4f8e.png" width="566" />
  </figure>
  <p id="Rdku"></p>
  <figure id="qgf2" class="m_original">
    <img src="https://img2.teletype.in/files/d6/72/d67212e8-b827-4650-85d9-7981a4a43eb9.png" width="727" />
  </figure>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@andrewholovko/uBJYhjbRCs8</guid><link>https://teletype.in/@andrewholovko/uBJYhjbRCs8?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko</link><comments>https://teletype.in/@andrewholovko/uBJYhjbRCs8?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=andrewholovko#comments</comments><dc:creator>andrewholovko</dc:creator><title>M04 Q40 What dependencies does spring-boot-starter-test brings to the classpath?</title><pubDate>Sat, 11 Sep 2021 10:28:58 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/20/42/2042bde0-a2b0-4ae1-8ba0-f6e3d3bd89c2.png"></media:content><category>Spting Boot Testing</category><description><![CDATA[<img src="https://img3.teletype.in/files/af/b9/afb94249-13b4-4d1b-82b3-a3ebc5636a00.png"></img>spring-boot-starter-test brings following dependencies:]]></description><content:encoded><![CDATA[
  <figure id="D56p" class="m_column">
    <img src="https://img3.teletype.in/files/af/b9/afb94249-13b4-4d1b-82b3-a3ebc5636a00.png" width="735" />
  </figure>
  <p id="703b">spring-boot-starter-test brings following dependencies:</p>
  <ul id="YOHO">
    <li id="fYk4">JUnit - Unit Testing for Java Applications</li>
    <li id="hy5d">Spring Test - Spring Framework Support for Testing</li>
    <li id="DQJ4">Spring Boot Test - Utilities and Integration Test Support for Spring Boot</li>
    <li id="D2Eu">AssertJ - Fluent Assertion Library</li>
    <li id="cxbb">Hamcrest - Matchers Library</li>
    <li id="MQPY">Mockito - Mocking Framework</li>
    <li id="YPXj">JSONassert - JSON Assertion Library</li>
    <li id="cKZb">JsonPath - XPath for JSON</li>
    <li id="bcmv">XMLUnit - Tools for XML verification</li>
  </ul>
  <p id="ZFxK">You can see list of all dependencies with versions for maven module by running following command:</p>
  <pre id="IXs4">mvn dependency:tree</pre>
  <pre id="b55a">[INFO] \- org.springframework.boot:spring-boot-starter-test:jar:2.1.4.RELEASE:test
[INFO]    +- org.springframework.boot:spring-boot-starter:jar:2.1.4.RELEASE:test
[INFO]    |  +- org.springframework.boot:spring-boot:jar:2.1.4.RELEASE:test
[INFO]    |  |  \- org.springframework:spring-context:jar:5.1.6.RELEASE:test
[INFO]    |  |     +- org.springframework:spring-aop:jar:5.1.6.RELEASE:test
[INFO]    |  |     +- org.springframework:spring-beans:jar:5.1.6.RELEASE:test
[INFO]    |  |     \- org.springframework:spring-expression:jar:5.1.6.RELEASE:test
[INFO]    |  +- org.springframework.boot:spring-boot-autoconfigure:jar:2.1.4.RELEASE:test
[INFO]    |  +- org.springframework.boot:spring-boot-starter-logging:jar:2.1.4.RELEASE:test
[INFO]    |  |  +- ch.qos.logback:logback-classic:jar:1.2.3:test
[INFO]    |  |  |  \- ch.qos.logback:logback-core:jar:1.2.3:test
[INFO]    |  |  +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.11.2:test
[INFO]    |  |  |  \- org.apache.logging.log4j:log4j-api:jar:2.11.2:test
[INFO]    |  |  \- org.slf4j:jul-to-slf4j:jar:1.7.26:test
[INFO]    |  +- javax.annotation:javax.annotation-api:jar:1.3.2:test
[INFO]    |  \- org.yaml:snakeyaml:jar:1.23:test
[INFO]    +- org.springframework.boot:spring-boot-test:jar:2.1.4.RELEASE:test
[INFO]    +- org.springframework.boot:spring-boot-test-autoconfigure:jar:2.1.4.RELEASE:test
[INFO]    +- com.jayway.jsonpath:json-path:jar:2.4.0:test
[INFO]    |  +- net.minidev:json-smart:jar:2.3:test
[INFO]    |  |  \- net.minidev:accessors-smart:jar:1.2:test
[INFO]    |  |     \- org.ow2.asm:asm:jar:5.0.4:test
[INFO]    |  \- org.slf4j:slf4j-api:jar:1.7.26:test
[INFO]    +- junit:junit:jar:4.12:test
[INFO]    +- org.assertj:assertj-core:jar:3.11.1:test
[INFO]    +- org.mockito:mockito-core:jar:2.23.4:test
[INFO]    |  +- net.bytebuddy:byte-buddy:jar:1.9.12:test
[INFO]    |  +- net.bytebuddy:byte-buddy-agent:jar:1.9.12:test
[INFO]    |  \- org.objenesis:objenesis:jar:2.6:test
[INFO]    +- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO]    +- org.hamcrest:hamcrest-library:jar:1.3:test
[INFO]    +- org.skyscreamer:jsonassert:jar:1.5.0:test
[INFO]    |  \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test
[INFO]    +- org.springframework:spring-core:jar:5.1.6.RELEASE:test
[INFO]    |  \- org.springframework:spring-jcl:jar:5.1.6.RELEASE:test
[INFO]    +- org.springframework:spring-test:jar:5.1.6.RELEASE:test
[INFO]    \- org.xmlunit:xmlunit-core:jar:2.6.2:test
[INFO]       \- javax.xml.bind:jaxb-api:jar:2.3.1:test
[INFO]          \- javax.activation:javax.activation-api:jar:1.2.0:test
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
</pre>

]]></content:encoded></item></channel></rss>