<?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: Gabriel N Voicu</title>
    <description>The latest articles on DEV Community by Gabriel N Voicu (@ngvoicu).</description>
    <link>https://dev.to/ngvoicu</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%2F354562%2F389b1ca4-bf4a-4ee2-8117-d3334ae54694.jpeg</url>
      <title>DEV Community: Gabriel N Voicu</title>
      <link>https://dev.to/ngvoicu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ngvoicu"/>
    <language>en</language>
    <item>
      <title>Premium multi layout Jekyll theme</title>
      <dc:creator>Gabriel N Voicu</dc:creator>
      <pubDate>Mon, 13 Dec 2021 07:44:11 +0000</pubDate>
      <link>https://dev.to/ngvoicu/premium-multi-layout-jekyll-theme-322h</link>
      <guid>https://dev.to/ngvoicu/premium-multi-layout-jekyll-theme-322h</guid>
      <description>&lt;ul&gt;
&lt;li&gt;Premium theme using Jekyll version 4.1.2 &amp;amp; Bootstrap 5&lt;/li&gt;
&lt;li&gt;Multipurpose (multiple homepage layouts)&lt;/li&gt;
&lt;li&gt;Fully ready for production within minutes&lt;/li&gt;
&lt;li&gt;Responsive, SEO Friendly, and Mobile optimized&lt;/li&gt;
&lt;li&gt;Step by step documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;USE: ZEESPIREHOLIDAYS code to get 35$ discount&lt;/p&gt;

&lt;p&gt;&lt;a href="https://shop.zeespire.com/"&gt;Checkout our demos&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Support: &lt;a href="mailto:office@zeespire.com"&gt;office@zeespire.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Details:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Three homepage designs which you can choose from&lt;/li&gt;
&lt;li&gt;Easily create and use your own Bootstrap designs&lt;/li&gt;
&lt;li&gt;Includes multiple blog posts and frontpage as sample content&lt;/li&gt;
&lt;li&gt;Customizable through config files and properties:&lt;/li&gt;
&lt;li&gt;show/hide authors&lt;/li&gt;
&lt;li&gt;show/hide dates&lt;/li&gt;
&lt;li&gt;show/hide social integrations&lt;/li&gt;
&lt;li&gt;show/hide watermark&lt;/li&gt;
&lt;li&gt;show/hide selected posts on the front page&lt;/li&gt;
&lt;li&gt;change footer color&lt;/li&gt;
&lt;li&gt;Has Authors, Posts, Categories features&lt;/li&gt;
&lt;li&gt;Supports multiple image sizes for fast loading&lt;/li&gt;
&lt;li&gt;Lightbox and Image galleries support&lt;/li&gt;
&lt;li&gt;Code snippets highlight&lt;/li&gt;
&lt;li&gt;Git helper scripts (.bat) for easy GIT interaction&lt;/li&gt;
&lt;li&gt;Jekyll helper scripts (.bat) to easily build or start HTTP server locally&lt;/li&gt;
&lt;li&gt;100% Responsive&lt;/li&gt;
&lt;li&gt;Many SEO features; Open Graph protocol; schema.org using Microdata; meta tags&lt;/li&gt;
&lt;li&gt;No dependency on external resources&lt;/li&gt;
&lt;li&gt;Track your visitors with Google Tag Manager or Google Analytics integration&lt;/li&gt;
&lt;li&gt;YouTube and other video website support for embedded videos&lt;/li&gt;
&lt;li&gt;Pinterest integration&lt;/li&gt;
&lt;li&gt;Links and icons to other social platforms like YouTube, Facebook, Instagram, Medium, TikTok, Pinterest (hidden if not needed)&lt;/li&gt;
&lt;li&gt;Search feature&lt;/li&gt;
&lt;li&gt;Clean code&lt;/li&gt;
&lt;li&gt;Favicons for all types of devices&lt;/li&gt;
&lt;li&gt;.htaccess redirects with HTTPS support&lt;/li&gt;
&lt;li&gt;Minimized HTML CSS and JS code on build for super speed&lt;/li&gt;
&lt;li&gt;Sitemap with latest modification date&lt;/li&gt;
&lt;li&gt;RSS feed&lt;/li&gt;
&lt;li&gt;Great documentation and support in max. 48 hours&lt;/li&gt;
&lt;li&gt;Easy to upgrade Jekyll and Bootstrap version&lt;/li&gt;
&lt;li&gt;Easy to deploy, customize and extend&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>jekyll</category>
      <category>html</category>
      <category>bootstrap</category>
      <category>seo</category>
    </item>
    <item>
      <title>Jumpstart Testing with Mockito and JUnit5</title>
      <dc:creator>Gabriel N Voicu</dc:creator>
      <pubDate>Thu, 02 Jul 2020 07:07:03 +0000</pubDate>
      <link>https://dev.to/ngvoicu/jumpstart-testing-with-mockito-and-junit5-13e8</link>
      <guid>https://dev.to/ngvoicu/jumpstart-testing-with-mockito-and-junit5-13e8</guid>
      <description>&lt;p&gt;In this article, we will see JUnit and Mockito in action using 2 Java components, a service class, and a repository class.&lt;/p&gt;

&lt;p&gt;We will start by creating the classes and then write tests in different ways to use concepts like, assert, verify, check for thrown exception, ArgumentMatcher and ArgumentCaptor. At last, we will create cleaner tests by extracting the duplicated code and even use Mockito annotations. We will not focus on having 100% code coverage.&lt;/p&gt;

&lt;p&gt;Code under test&lt;br&gt;
DataRepository.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public interface DataRepository {
    int[] retrieveAllData();
    int getStoredSumById(int id);
    void save(Object o);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DataService.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public interface DataService {
    int calculateSum();
    void setDataRepository(DataRepository dataRepository);
    int calculateNewSum(int id);
    void save(Data o);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DataServiceImpl.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class DataServiceImpl implements DataService {

    private DataRepository dataRepository;

    public void setDataRepository(DataRepository dataRepository) {
        this.dataRepository = dataRepository;
    }

    public int calculateSum(){
        int sum = 0;
        for(int value : dataRepository.retrieveAllData()){
            sum += value;
        }
        return sum;
    }

    public int calculateNewSum(int id){
        int sum = dataRepository.getStoredSumById(id);
        return sum + sum;
    }

    public void save(Data o){
        o = new Data(o.getName().toUpperCase());
        dataRepository.save(o);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Data.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Data {
    private String name;
    // constructors, getters and setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unit tests without Mockito annotations&lt;br&gt;
Test for calculateSum() method from service class, mocking repository. In this test, we are assuming that the retrieveAllData() mocked method from the repository returns an array with data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
public void calculateSum_Should_ReturnResult_When_DataIsProvided() {
    //create service under test
    DataService ms = new DataServiceImpl();

    //mock repository to test service in isolation
    DataRepository dataRepositoryMock = mock(DataRepository.class);
    when(dataRepositoryMock.retrieveAllData()).thenReturn(new int[]{1, 2, 3});

    //set mock to service
    ms.setDataRepository(dataRepositoryMock);

    //call method under test
    int result = ms.calculateSum();

    //verify if method on the mock is called by service under test
    //it is mostly used when a method that is called on a mock does not have a return
    verify(dataRepositoryMock, times(1)).retrieveAllData();

    //assert result
    assertEquals(6, result);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test for calculateSum() method from service class, mocking repository. We are assuming that the retrieveAllData() mocked method from the repository returns an array without data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
public void calculateSum_Should_ReturnZero_When_DataIsEmpty() {
    //create service under test
    DataService ms = new DataServiceImpl();

    //mock repository to test service in isolation
    DataRepository dataRepositoryMock = mock(DataRepository.class);
    when(dataRepositoryMock.retrieveAllData()).thenReturn(new int[]{});

    //set mock to service
    ms.setDataRepository(dataRepositoryMock);

    //call method under test
    int result = ms.calculateSum();

    //verify if method on the mock is called by service under test
    verify(dataRepositoryMock, times(1)).retrieveAllData();

    //assert result
    assertEquals(0, result);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test for calculateSum() method from service class, mocking repository. Assuming that retrieveAllData() mocked method from the repository returns null, causing the calculateSum() method from service class to throw a NullPointerException.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
public void calculateSum_Should_ThrowException_When_DataIsNull() {
    assertThrows(NullPointerException.class, () -&amp;gt; {
        //create service under test
        DataService ms = new DataServiceImpl();

        //mock repository to test service in isolation
        DataRepository dataRepositoryMock = mock(DataRepository.class);
        when(dataRepositoryMock.retrieveAllData()).thenReturn(null);

        //set mock to service
        ms.setDataRepository(dataRepositoryMock);

        //call method under test
        ms.calculateSum();
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test for calculateNewSum() method from service class, mocking repository using ArgumentMatchers. In this test, we are assuming that getStoredSumById() mocked method from the repository returns 2. The new topic introduced here are ArgumentMatchers like any(), anyInt(), etc. that can be used to replace an actual argument to make tests more generic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
void calculateNewSum_Should_ReturnResult_When_DataIsProvided() {
    //create service under test
    DataService ms = new DataServiceImpl();

    //mock repository to test service in isolation
    DataRepository dataRepositoryMock = mock(DataRepository.class);

    //return 2 when method is called with any int value
    when(dataRepositoryMock.getStoredSumById(anyInt())).thenReturn(2);

    //set mock to service
    ms.setDataRepository(dataRepositoryMock);

    //call method under test
    int result = ms.calculateNewSum(1);

    //verify if method on the mock is called by service under test with any argument
    verify(dataRepositoryMock, times(1)).getStoredSumById(anyInt());

    //assert result
    assertEquals(4, result);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test for save() method from service class, mocking repository. In this case, the save() method from the service class doesn’t return anything to be asserted. We can use an ArgumentCaptor to check if the save() method from the repository class is called with expected arguments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
void save_ShouldCallRepository_With_GivenParam() {
    // create service under test
    DataService ms = new DataServiceImpl();

    // mock repository to test service in isolation
    DataRepository dataRepositoryMock = mock(DataRepository.class);

    // set mock to service
    ms.setDataRepository(dataRepositoryMock);

    // call method under test
    Data o = new Data("MockitoObject");
    ms.save(o);

    //create expected object
    Data expected = new Data("MOCKITOOBJECT");

    // because the method does not return anything we can check
    // if mock method was called with an expected parameter
    ArgumentCaptor&amp;lt;Data&amp;gt; captor = ArgumentCaptor.forClass(Data.class);
    verify(dataRepositoryMock, times(1)).save(captor.capture());

    //assert captured argument
    assertEquals(expected, captor.getValue());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The entire article was published at &lt;a href="https://weinspire.tech"&gt;https://weinspire.tech&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mockito</category>
      <category>junit</category>
      <category>java</category>
      <category>testing</category>
    </item>
    <item>
      <title>Hexagonal Architecture</title>
      <dc:creator>Gabriel N Voicu</dc:creator>
      <pubDate>Wed, 25 Mar 2020 15:58:49 +0000</pubDate>
      <link>https://dev.to/ngvoicu/hexagonal-architecture-la8</link>
      <guid>https://dev.to/ngvoicu/hexagonal-architecture-la8</guid>
      <description>&lt;h2&gt;1. Overview&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hexagonal Architecture is an architectural design pattern&lt;/strong&gt; that makes the application highly maintainable and fully testable.&lt;br&gt;
It keeps the important parts of the application isolated from outer components.&lt;br&gt;
&lt;strong&gt;Components are integrated into the core through ports and adapters.&lt;/strong&gt;&lt;br&gt;
The core comprises business logic and domain layers.&lt;br&gt;
Also known as Ports and Adapters Pattern it has a lot of benefits visible in the long term.&lt;br&gt;
&lt;strong&gt;Above all, testing and changing the application are easy and cost-effective.&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VkmbVoGZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iexkpv3tc1uyaj60gv1c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VkmbVoGZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iexkpv3tc1uyaj60gv1c.png" alt="drawing" width="768" height="635"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The entire article was published at &lt;a href="https://weinspire.tech"&gt;https://weinspire.tech&lt;/a&gt; on October 18, 2019.&lt;/p&gt;

</description>
      <category>java</category>
      <category>architecture</category>
      <category>principles</category>
    </item>
  </channel>
</rss>
