【问题标题】:Why Junit assertThat() passes for two objects depsite the objects being unequal?为什么 Junit assertThat() 传递两个对象,尽管对象不相等?
【发布时间】:2021-08-11 15:26:25
【问题描述】:

我在 Junit 测试用例中比较了同一类 EMSResponse 的两个对象 emsResponseexpectedEMSResponse,但 assertThat(...) 测试用例通过了,尽管对象不相等。当我在两个对象上尝试正常的equals 时,输出为假,但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 类的详细信息时,我得到以下输出:

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

【问题讨论】:

    标签: junit lombok spring-test


    【解决方案1】:

    我认为您没有正确使用 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

    【讨论】:

      【解决方案2】:

      这不会因为您没有正确使用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);
      

      这应该可以帮助您理解:

      【讨论】:

      • 谢谢!我改为 assertTrue(expectedEMSResponse==emsResponse);现在得到一个 java.lang.AssertionError。知道为什么吗?
      • ... 可能是因为表达式 expectedEMSResponse==emsResponse 不正确。
      【解决方案3】:

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

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

      当您调用assertThat(expectedEMSResponse==eMSResponse) 时,AssertJ 只返回一个布尔类型的断言对象,不会发生其他任何事情。

      正确的使用方法是:

      assertThat(eMSResponse).isEqualTo(expectedEMSResponse);
      

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

      【讨论】:

      • 没错。我没有注意到这一点。我已将调用更改为 assertTrue(expectedEMSResponse==emsResponse);并以 java.lang.AssertionError 告终。知道我做错了什么吗?
      • 如果我这样做 assertThat(emsResponse.getOutput().getTransId()).isEqualTo(expectedEMSResponse.getOutput().getTransId());这工作正常并通过了测试用例
      猜你喜欢
      • 1970-01-01
      • 2023-01-26
      • 2014-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多