raikumardipak
raikumardipak

Reputation: 1585

Why Junit assertThat() passes for two objects depsite the objects being unequal?

I am comparing two objects emsResponse and expectedEMSResponse of the same class EMSResponse in a Junit test case but the assertThat(...) test case passes despite the objects being unequal. When I try a normal equals on the two objects the output is false but the assertThat(expectedEMSResponse==eMSResponse) still passes rather than failing. Please advise.

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString
@EqualsAndHashCode
public class RestconfRes {
    
    private String response;
    private int httpStatusCode;
}


@Getter
@Setter
@ToString
@EqualsAndHashCode(callSuper = true)
public class EMSResponse extends RestconfRes {
    
    private EMSOutput output;
    private EMSErrors errors;
    private String message;
    
    public EMSOutput getOutput() {
        if (output == null) {
            output = new EMSOutput();
        }
        return output;
    }
}

// Junit test case

 @Test
        public void processJMSRequestForHappyPathTest() throws Exception {
            // test case logic here
            // mock logic here
EMSResponse emsResponse = processor.processJMSRequest(request);
            System.out.println(" expectedEMSResponse ..." + EMSResponse.toString());
            System.out.println(" processJMSRequestForHappyPathTest expectedEMSResponse  ...:" + expectedEMSResponse.toString());
            System.out.println("check if i am equal..."+ expectedEMSResponse.equals(emsResponse));
            assertThat(expectedEMSResponse==eMSResponse);
        }

Output:

expectedEMSResponse ...EMSResponse(output=EMSoutput(deviceName=null, timestamp=null, status=failure, transId=null, completionStatus=null, serviceId=null, contentProviderName=null, interfaceName=null), errors=EMSerrors(errorType=INTERNAL_FAILURE, errorTag=A41_INTERNAL_EXCEPTION, errorMessage=An internal error occurred within A41. Please contact ASG.), message=null)

emsResponse ...EMSResponse(output=EMSoutput(deviceName=device_3, timestamp=2020-07-15T16:32:31.881000, status=configuring, transId=66427-d8b5-489f-9f8f, completionStatus=in-progress, serviceId=null, contentProviderName=null, interfaceName=null), errors=null, message=null)

check if i am equal...false

Updated second sub question to this I changed the call to:

assertTrue(expectedEMSResponse==emsResponse);
// gives a java.lang.AssertionError and 
System.out.println("check if i am equal..."+ expectedEMSResponse.equals(emsResponse)); gives output 
check if i am equal...false

// this test case passes Ok assertThat(emsResponse.getOutput().getTransId()).isEqualTo(expectedEMSResponse.getOutput().getTransId());

When I try printing the details of the emsResponse and expecteEMSResponse classes through toString() I get the below output:

// gives only a bean as an output
emsResponse.toString():com.myorg.myapp.interfaces.dto.emsResponse#0 bean

//gives the complete object signature
expectedemsResponse.toString():emsResponse(output=emsOutput(deviceName=device_3, 
timestamp=2020-07-15T16:32:31.881000, status=configuring, transId=hello-there-489f-9f8f-abcd, 
completionStatus=in-progress, serviceId=null, contentProviderName=null, interfaceName=null), errors=null, message=null)

Upvotes: 0

Views: 1238

Answers (3)

Arho Huttunen
Arho Huttunen

Reputation: 1131

You are probably using AssertJ because I don't think JUnit 4 or Hamcrest have a single argument version of assertThat(), and JUnit 5 doesn't have such method.

The way AssertJ assertThat() works is that the first argument of the call is the actual value that you want to perform assertions on. This returns an assertion object, which provides you a number of assertion methods.

When you call assertThat(expectedEMSResponse==eMSResponse), AssertJ just returns an assertion object for boolean type and nothing else happens.

The correct way to use it would be:

assertThat(eMSResponse).isEqualTo(expectedEMSResponse);

Now it returns an assertion object for the first argument, and then performs the isEqualTo() assertion on that one. The assertThat() call only works as an entry point to different assertions that can be performed on the first argument.

Upvotes: 2

NoDataFound
NoDataFound

Reputation: 11959

This does not fail because you are not using junit correctly:

        @Test
        public void processJMSRequestForHappyPathTest() throws Exception {
            // test case logic here
            // mock logic here
EMSResponse emsResponse = processor.processJMSRequest(request);
            System.out.println(" expectedEMSResponse ..." + EMSResponse.toString());
            System.out.println(" processJMSRequestForHappyPathTest expectedEMSResponse  ...:" + expectedEMSResponse.toString());
            System.out.println("check if i am equal..."+ expectedEMSResponse.equals(emsResponse));
            assertThat(expectedEMSResponse==eMSResponse);
        }

You should have:

            assertTrue(expectedEMSResponse==eMSResponse);
            assertEquals(expectedEMSResponse, eMSResponse);

Or using assertThat with assertj:

assertThat(eMSResponse).isEqualTo(expectedEMSResponse);

This should help you understand:

Upvotes: 1

atprra
atprra

Reputation: 114

I don't think you are using assertThat correctly. Looks like you need to pass additional arguments as well. These are the method definitions:

assertThat(T actual, Matcher<? super T> matcher)

assertThat(String reason, T actual, Matcher<? super T> matcher)

Also as per the documentation, it is deprecated. Might I suggest that you use assertEquals() instead?

The documentation: https://junit.org/junit4/javadoc/latest/org/junit/Assert.html#assertThat

Upvotes: 1

Related Questions