<?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: Vishal Bhavsar</title>
    <description>The latest articles on DEV Community by Vishal Bhavsar (@vishal_bhavsar).</description>
    <link>https://dev.to/vishal_bhavsar</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%2F1387085%2F6e281a40-0902-4adf-ab42-579cfd6167de.png</url>
      <title>DEV Community: Vishal Bhavsar</title>
      <link>https://dev.to/vishal_bhavsar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vishal_bhavsar"/>
    <language>en</language>
    <item>
      <title>Resolve conflicts during Git merge and rebase</title>
      <dc:creator>Vishal Bhavsar</dc:creator>
      <pubDate>Fri, 05 Jul 2024 21:25:18 +0000</pubDate>
      <link>https://dev.to/vishal_bhavsar/resolve-conflicts-during-git-merge-and-rebase-3fij</link>
      <guid>https://dev.to/vishal_bhavsar/resolve-conflicts-during-git-merge-and-rebase-3fij</guid>
      <description>&lt;p&gt;Say, you have &lt;code&gt;main&lt;/code&gt; &amp;amp; &lt;code&gt;feature&lt;/code&gt; as 2 branches.&lt;/p&gt;

&lt;h2&gt;
  
  
  Merge conflicts
&lt;/h2&gt;

&lt;p&gt;If you want to merge &lt;code&gt;feature&lt;/code&gt; branch into &lt;code&gt;main&lt;/code&gt;, run following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout main
git merge feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can result in merge conflicts.&lt;/p&gt;

&lt;p&gt;To discard all changes in &lt;code&gt;feature&lt;/code&gt; and accept everything on &lt;code&gt;main&lt;/code&gt;, run following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git merge -Xours feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To accept changes from &lt;code&gt;feature&lt;/code&gt; branch, run below command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git merge -Xtheirs feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Rebase conflicts
&lt;/h2&gt;

&lt;p&gt;If you want to rebase &lt;code&gt;feature&lt;/code&gt; branch onto &lt;code&gt;main&lt;/code&gt;, run below command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout feature
git rebase main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, this can result in merge conflicts.&lt;br&gt;
To accept the changes in &lt;code&gt;feature&lt;/code&gt; branch, run below command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git rebase main -Xtheirs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To accept the changes in &lt;code&gt;main&lt;/code&gt; branch, run below command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git rebase main -Xours
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Gradle + AspectJ + JUnit5</title>
      <dc:creator>Vishal Bhavsar</dc:creator>
      <pubDate>Sun, 31 Mar 2024 17:47:46 +0000</pubDate>
      <link>https://dev.to/vishal_bhavsar/gradle-aspectj-junit5-testing-3b12</link>
      <guid>https://dev.to/vishal_bhavsar/gradle-aspectj-junit5-testing-3b12</guid>
      <description>&lt;h2&gt;
  
  
  Problem Statement
&lt;/h2&gt;

&lt;p&gt;When running &lt;code&gt;JUnit5&lt;/code&gt; tests using &lt;code&gt;Gradle&lt;/code&gt; in Java, I wanted to log the arguments, that a method was receiving. One way was to put logger just before the method is executed. However, there are 2 challenges:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If the method is being used 100 times, we have to add the logger in all 100 places.&lt;/li&gt;
&lt;li&gt;If the method is in 3rd party library, there are limitations and you can't really know what that method is actually receiving internally.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this tutorial, I will use the following example.&lt;br&gt;
My test case is validating that the input string is not null or blank. Here, I am using &lt;code&gt;assertj-core&lt;/code&gt; library. So, my test case looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

@Test
@DisplayName("Verify string is not null &amp;amp; blank.")
public void testStringNotNull() {
    var input = "Hello world!";
    Assertions.assertThat(input).isNotBlank();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Aspect Oriented Programming(AOP)
&lt;/h3&gt;

&lt;p&gt;We can use the concept of AOP to weave some code at compile time and execute it before/after/around the desired method.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-requisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I am using below softwares:

&lt;ul&gt;
&lt;li&gt;Gradle: 8.6&lt;/li&gt;
&lt;li&gt;Java: 17.0.10&lt;/li&gt;
&lt;li&gt;Groovy: 3.0.17&lt;/li&gt;
&lt;li&gt;Kotlin: 1.9.20&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;We are using &lt;code&gt;aspectj&lt;/code&gt; library to weave the code.&lt;/li&gt;

&lt;li&gt;This tutorial is specifically for tests residing in &lt;code&gt;/src/test/java&lt;/code&gt;. However, with minor changes, you can achieve the same results for the code residing in &lt;code&gt;/src/main/java&lt;/code&gt;.&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Modify build.gradle
&lt;/h3&gt;

&lt;p&gt;Add plugin declaration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plugins {
    // Other plugin declarations
    id "io.freefair.aspectj.post-compile-weaving" version "8.6"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add &lt;code&gt;aspectj&lt;/code&gt; dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies {
    implementation "org.aspectj:aspectjrt:1.9.22"
    implementation "org.aspectj:aspectjweaver:1.9.22"

    // Other dependencies
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add following snippet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;compileTestJava {
    ajc {
        options {
            aspectpath.setFrom configurations.aspect
            compilerArgs = ["-Xlint:ignore", "-Xajruntimetarget:1.5"]
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Add Aspect &amp;amp; advise
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;

@Slf4j
@Aspect
public class LoggingAspect {
    @SneakyThrows
    @Before("call(* org.assertj.core.api.Assertions.assertThat(..))")
    public void beforeAssert(final JoinPoint joinPoint) {
        log.debug("Execution before invocation of AbstractCharSequenceAssert.isNotBlank().");
        final var args = joinPoint.getArgs();
        var method = MethodSignature.class.cast(joinPoint.getSignature()).getMethod();
        final var parameters = method.getParameters();
        for (int i = 0; i &amp;lt; parameters.length; i++) {
            final Class&amp;lt;?&amp;gt; parameterType = parameters[i].getType();
            final var parameterValue = args[i];
            log.info("Param type: {}, value: {}", parameterType, parameterValue);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This class represents an &lt;code&gt;Aspect&lt;/code&gt;, which cuts across multiple objects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Before("call(* org.assertj.core.api.Assertions.assertThat(..))")
public void beforeAssert(final JoinPoint joinPoint) {
    // code
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line defines the &lt;code&gt;before&lt;/code&gt; advice. The method should return void. The method should be declared public. It takes 1 parameter of type &lt;code&gt;JoinPoint&lt;/code&gt;. The value for this annotation is the regular expression of advice declaration.&lt;/p&gt;

&lt;p&gt;Here, in this example, we are specifying to execute code before the invocation of &lt;code&gt;Assertions.assertThat()&lt;/code&gt;. Any custom logic that you want to perform goes inside the &lt;code&gt;beforeAssert()&lt;/code&gt; method. Here, I am extracting the parameters &amp;amp; their values of a method being intercepted, in this case &lt;code&gt;Assertions.assertThat(input)&lt;/code&gt;. As you can see &lt;code&gt;assertThat()&lt;/code&gt; method is taking only 1 parameter of type &lt;code&gt;java.lang.String&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once you run the code, you should see the following output in the console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Execution before invocation of AbstractCharSequenceAssert.isNotBlank().
Param type: class java.lang.String, value: Hello world!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Few things to remember
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Your aspect needs to be in the same sources root as your tests. i.e. &lt;code&gt;src/test/java&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gradle</category>
      <category>java</category>
      <category>aspectj</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
