'How to write Junit for clone method catch block

My respected java developer friends. i am trying test and cover the catch block of clone method. I have wasted one week but didn't find any solution to cover catch block. Please help me.

My source code -

public class Data implements Cloneable {

    private String A;

    @Override
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            return new Data();
        }
    }
}

My Junit Test Cases -

@Test
public void testCloneSucess() throws CloneNotSupportedException {
    Data data = new Data();
    Data d = (Data) data.clone();
    assertNotNull(d);
}

@Test
public void testCloneFailure() throws CloneNotSupportedException {
    Data data = new Data();
    doThrow(new CloneNotSupportedException()).when(data.clone());
    assertThrows(CloneNotSupportedException.class, () -> data.clone());
}

i have given links for the images, this will give more understanding of question and what i have tried.

  1. Source code - source code
  2. junit that i have tried - junits


Solution 1:[1]

A few things before I answer your question:

  1. return new Data(); doesn't actually clone anything because the A field in returned the object is not guaranteed to be the same as this.A. You can fix this by doing something like

    Data other = new Data();
    other.A = this.A
    return other;
    
  2. But now your custom implementation has the exact same behavior as Object.clone(), so there is no reason for it. Generally, you only need to implement Cloneable. You don't need to override clone() unless you have some very special processing needed that doesn't happen with the bitwise clone which Object already gives us.

With that said, to test the path that throws an exception, you need to create a condition where something in the try block throws the specific exception you want to test. In this case, the only choice is to cause super.clone() to throw CloneNotSupportedException. That means you have to mock Object.clone and cause it to throw the exception.

Additionally, you don't want to assertThrows(CloneNotSupportedException.class, () -> data.clone()); because Data.clone() never throws this exception. Instead, you need an assertion that is based on the expected behavior in the catch block. In this case, that something is returned.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Code-Apprentice