为什么 Junit assertThat() 传递给两个对象,尽管对象不相等?

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

我正在比较 Junit 测试用例中相同 class EMSResponse 的两个对象 emsResponseexpectedEMSResponse,但是尽管 assertThat(...) 测试用例通过了对象 不相等 。当我在两个对象上尝试正常 equals 时,输出为 false 但 assertThat(expectedEMSResponse==eMSResponse) 仍然通过而不是失败。请指教

@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
        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);
        }

输出:

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

将第二个子问题更新到此 我将调用更改为:

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

// 这个测试用例通过 Ok assertThat(emsResponse.getOutput().getTransId()).isEqualTo(expectedEMSResponse.getOutput().getTransId());

当我尝试通过 toString() 打印 emsResponseexpecteEMSResponse classes 的详细信息时,我得到以下输出:

// 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)

我认为您没有正确使用 assertThat。看起来您还需要传递其他参数。这些是方法定义:

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

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

另外根据文档,它已被弃用。我可以建议您改用 assertEquals() 吗?

文档:https://junit.org/junit4/javadoc/latest/org/junit/Assert.html#assertThat

这不会失败,因为您没有正确使用 junit:

        @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);
        }

你应该有:

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

或使用 assertThatassertj:

assertThat(eMSResponse).isEqualTo(expectedEMSResponse);

这应该可以帮助您理解:

您可能正在使用 AssertJ,因为我认为 JUnit 4 或 Hamcrest 没有 assertThat() 的单参数版本,而 JUnit 5 没有这样的方法。

AssertJ assertThat() 的工作方式是调用的第一个参数是您要对其执行断言的实际值。 returns 一个断言对象,它为您提供了多种断言方法。

当您调用 assertThat(expectedEMSResponse==eMSResponse) 时,AssertJ 只是 returns 布尔类型的断言对象,没有其他任何事情发生。

正确的使用方法是:

assertThat(eMSResponse).isEqualTo(expectedEMSResponse);

现在它 returns 第一个参数的断言对象,然后对该参数执行 isEqualTo() 断言。 assertThat() 调用仅作为可对第一个参数执行的不同断言的入口点。