使用mockito在抽象匿名类中测试void方法

时间:2017-12-12 00:54:09

标签: java junit mockito abstract-class anonymous-class

我无法测试抽象类实例中的方法。我已经尝试了几种方法,并想知道是否可以这样做。抽象类的内容可以在下面的链接中看到。

Jacoco Class Report

Belows是JUnit和Mockito测试,我试图测试上图中的案例。

@RunWith(MockitoJUnitRunner.class)
public class PahoRxMqttCallbackTest {

  @Test
  public void whenConnectionLostOccurs() {
    PahoRxMqttCallback rxMqttCallback = mock(PahoRxMqttCallback.class);
    assertThat(rxMqttCallback).isNotNull();

    PahoRxMqttException exception = new PahoRxMqttException(
        new MqttException(MqttException.REASON_CODE_CONNECTION_LOST));

    ArgumentCaptor<Throwable> onConnectionLostCauseArgumentCaptor = ArgumentCaptor.forClass(Throwable.class);

    rxMqttCallback.connectionLost(exception);

    verify(rxMqttCallback).connectionLost(onConnectionLostCauseArgumentCaptor.capture());

    assertThat(onConnectionLostCauseArgumentCaptor.getValue()).isNotNull();
    assertThat(onConnectionLostCauseArgumentCaptor.getValue()).isInstanceOf(PahoRxMqttException.class);
    assertThat(onConnectionLostCauseArgumentCaptor.getValue()).hasCauseInstanceOf(MqttException.class);
    assertThat(onConnectionLostCauseArgumentCaptor.getValue()).isEqualTo(exception);
  }

  @Test
  public void whenConnectCompleteOccurs() {
    PahoRxMqttCallback rxMqttCallback = mock(PahoRxMqttCallback.class);
    assertThat(rxMqttCallback).isNotNull();

    boolean reconnect = true;
    String brokerUri = "tcp://localhost:1883";

    ArgumentCaptor<Boolean> onConnectCompleteReconnectArgumentCaptor = ArgumentCaptor.forClass(Boolean.class);
    ArgumentCaptor<String> onConnectCompleteServerUriArgumentCaptor = ArgumentCaptor.forClass(String.class);

    rxMqttCallback.connectComplete(reconnect, brokerUri);

    verify(rxMqttCallback).connectComplete(
        onConnectCompleteReconnectArgumentCaptor.capture(),
        onConnectCompleteServerUriArgumentCaptor.capture());

    assertThat(onConnectCompleteReconnectArgumentCaptor.getValue()).isNotNull();
    assertThat(onConnectCompleteReconnectArgumentCaptor.getValue()).isEqualTo(reconnect);
    assertThat(onConnectCompleteServerUriArgumentCaptor.getValue()).isNotNull();
    assertThat(onConnectCompleteServerUriArgumentCaptor.getValue()).isEqualTo(brokerUri);
  }

  @Test
  public void whenDeliveryCompleteOccurs() {
    PahoRxMqttCallback rxMqttCallback = mock(PahoRxMqttCallback.class);
    assertThat(rxMqttCallback).isNotNull();

    IMqttDeliveryToken deliveryToken = mock(IMqttDeliveryToken.class);
    assertThat(deliveryToken).isNotNull();

    RxMqttToken rxMqttToken = new PahoRxMqttToken(deliveryToken);

    //ArgumentCaptor<IMqttDeliveryToken> onDeliveryCompleteTokenArgumentCaptor = ArgumentCaptor.forClass(IMqttDeliveryToken.class);
    ArgumentCaptor<RxMqttToken> onDeliveryCompleteRxTokenArgumentCaptor = ArgumentCaptor.forClass(RxMqttToken.class);

    //rxMqttCallback.deliveryComplete(deliveryToken);
    rxMqttCallback.deliveryComplete(rxMqttToken);

    /*
     * Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
     * Mocking methods declared on non-public parent classes is not supported.
     */
    //verify(rxMqttCallback).deliveryComplete(onDeliveryCompleteTokenArgumentCaptor.capture());
    verify(rxMqttCallback).deliveryComplete(onDeliveryCompleteRxTokenArgumentCaptor.capture());

    //assertThat(onDeliveryCompleteTokenArgumentCaptor.getValue()).isNotNull();
    //assertThat(onDeliveryCompleteTokenArgumentCaptor.getValue()).isExactlyInstanceOf(IMqttDeliveryToken.class);
    //assertThat(onDeliveryCompleteTokenArgumentCaptor.getValue()).isEqualTo(deliveryToken);

    assertThat(onDeliveryCompleteRxTokenArgumentCaptor.getValue()).isNotNull();
    assertThat(onDeliveryCompleteRxTokenArgumentCaptor.getValue()).isExactlyInstanceOf(PahoRxMqttToken.class);
    assertThat(onDeliveryCompleteRxTokenArgumentCaptor.getValue()).isEqualTo(rxMqttToken);
  }

  //@Test
  public void whenMessageArrived() throws Exception {
    PahoRxMqttCallback rxMqttCallback = mock(PahoRxMqttCallback.class);
    assertThat(rxMqttCallback).isNotNull();

    String topic = "topic";
    MqttMessage message = new MqttMessage();

    ArgumentCaptor<String> onMessageArrivedTopicArgumentCaptor = ArgumentCaptor.forClass(String.class);
    ArgumentCaptor<MqttMessage> onMessageArrivedMessageArgumentCaptor = ArgumentCaptor.forClass(MqttMessage.class);

    rxMqttCallback.messageArrived(topic, message);

    /*
     * Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
     * Mocking methods declared on non-public parent classes is not supported.
     */
    verify(rxMqttCallback).messageArrived(onMessageArrivedTopicArgumentCaptor.capture(), onMessageArrivedMessageArgumentCaptor.capture());

    assertThat(onMessageArrivedTopicArgumentCaptor.getValue()).isNotNull();
    assertThat(onMessageArrivedTopicArgumentCaptor.getValue()).isEqualTo(topic);

    assertThat(onMessageArrivedMessageArgumentCaptor.getValue()).isNotNull();
    assertThat(onMessageArrivedMessageArgumentCaptor.getValue()).isEqualTo(message);
  }

}

即使在网上搜索它之后我也无法做到。所以我很感激帮助。

更新

我能够执行测试并涵盖Jacoco所显示的所有警报。但为此,我必须为抽象类创建一个实现,而不是使用匿名类。可以在以下链接中看到

Jacoco Class Report 2

更新的单元测试:

@RunWith(MockitoJUnitRunner.class)
public class PahoRxMqttCallbackTest {

  @Test
  public void whenConnectionLostOccurs() {
    PahoRxMqttCallback rxMqttCallback = spy(PahoRxMqttCallback.create(cause -> {}, (recon, uri) -> {}, t -> {}));

    PahoRxMqttException exception = new PahoRxMqttException(
        new MqttException(MqttException.REASON_CODE_CONNECTION_LOST));

    ArgumentCaptor<Throwable> onConnectionLostCauseArgumentCaptor = ArgumentCaptor.forClass(Throwable.class);

    rxMqttCallback.connectionLost(exception);

    verify(rxMqttCallback).connectionLost(onConnectionLostCauseArgumentCaptor.capture());

    assertThat(onConnectionLostCauseArgumentCaptor.getValue()).isNotNull();
    assertThat(onConnectionLostCauseArgumentCaptor.getValue()).isInstanceOf(PahoRxMqttException.class);
    assertThat(onConnectionLostCauseArgumentCaptor.getValue()).hasCauseInstanceOf(MqttException.class);
    assertThat(onConnectionLostCauseArgumentCaptor.getValue()).isEqualTo(exception);
  }

  @Test
  public void whenConnectCompleteOccurs() {
    PahoRxMqttCallback rxMqttCallback = spy(PahoRxMqttCallback.create(cause -> {}, (r, u) -> {}, t -> {}));

    boolean reconnect = true;
    String brokerUri = "tcp://localhost:1883";

    ArgumentCaptor<Boolean> onConnectCompleteReconnectArgumentCaptor = ArgumentCaptor.forClass(Boolean.class);
    ArgumentCaptor<String> onConnectCompleteServerUriArgumentCaptor = ArgumentCaptor.forClass(String.class);

    rxMqttCallback.connectComplete(reconnect, brokerUri);

    verify(rxMqttCallback).connectComplete(
        onConnectCompleteReconnectArgumentCaptor.capture(),
        onConnectCompleteServerUriArgumentCaptor.capture());

    assertThat(onConnectCompleteReconnectArgumentCaptor.getValue()).isNotNull();
    assertThat(onConnectCompleteReconnectArgumentCaptor.getValue()).isEqualTo(reconnect);
    assertThat(onConnectCompleteServerUriArgumentCaptor.getValue()).isNotNull();
    assertThat(onConnectCompleteServerUriArgumentCaptor.getValue()).isEqualTo(brokerUri);
  }

  @Test
  public void whenDeliveryCompleteOccurs() {
    PahoRxMqttCallback rxMqttCallback = spy(PahoRxMqttCallback.create(cause -> {}, (r, u) -> {}));

    IMqttDeliveryToken deliveryToken = new MqttDeliveryToken();

    RxMqttToken rxMqttToken = new PahoRxMqttToken(deliveryToken);

    ArgumentCaptor<IMqttDeliveryToken> onDeliveryCompleteTokenArgumentCaptor = ArgumentCaptor.forClass(IMqttDeliveryToken.class);
    ArgumentCaptor<RxMqttToken> onDeliveryCompleteRxTokenArgumentCaptor = ArgumentCaptor.forClass(RxMqttToken.class);

    rxMqttCallback.deliveryComplete(deliveryToken);
    rxMqttCallback.deliveryComplete(rxMqttToken);

    verify(rxMqttCallback).deliveryComplete(onDeliveryCompleteTokenArgumentCaptor.capture());
    verify(rxMqttCallback, times(2)).deliveryComplete(onDeliveryCompleteRxTokenArgumentCaptor.capture());

    assertThat(onDeliveryCompleteTokenArgumentCaptor.getValue()).isNotNull();
    assertThat(onDeliveryCompleteTokenArgumentCaptor.getValue()).isExactlyInstanceOf(MqttDeliveryToken.class);
    assertThat(onDeliveryCompleteTokenArgumentCaptor.getValue()).isEqualTo(deliveryToken);

    assertThat(onDeliveryCompleteRxTokenArgumentCaptor.getValue()).isNotNull();
    assertThat(onDeliveryCompleteRxTokenArgumentCaptor.getValue()).isExactlyInstanceOf(PahoRxMqttToken.class);
    assertThat(onDeliveryCompleteRxTokenArgumentCaptor.getValue()).isEqualTo(rxMqttToken);
  }

  @Test
  public void whenMessageArrived() throws Exception {
    PahoRxMqttCallback rxMqttCallback = spy(PahoRxMqttCallback.create(cause -> {}, (r, u) -> {}, t -> {}));

    String topic = "topic";
    MqttMessage message = new MqttMessage();

    ArgumentCaptor<String> onMessageArrivedTopicArgumentCaptor = ArgumentCaptor.forClass(String.class);
    ArgumentCaptor<MqttMessage> onMessageArrivedMessageArgumentCaptor = ArgumentCaptor.forClass(MqttMessage.class);

    rxMqttCallback.messageArrived(topic, message);

    verify(rxMqttCallback).messageArrived(onMessageArrivedTopicArgumentCaptor.capture(), onMessageArrivedMessageArgumentCaptor.capture());

    assertThat(onMessageArrivedTopicArgumentCaptor.getValue()).isNotNull();
    assertThat(onMessageArrivedTopicArgumentCaptor.getValue()).isEqualTo(topic);

    assertThat(onMessageArrivedMessageArgumentCaptor.getValue()).isNotNull();
    assertThat(onMessageArrivedMessageArgumentCaptor.getValue()).isEqualTo(message);
  }

}

1 个答案:

答案 0 :(得分:0)

你永远不会实例化这个类,只有类的模拟。

 PahoRxMqttCallback rxMqttCallback = mock(PahoRxMqttCallback.class);

模拟不是真正的类,只是假副本。

相反,你应该做

 PahoRxMqttCallback rxMqttCallback = new PahoRxMqttCallback();

 PahoRxMqttCallback rxMqttCallback = spy(new PahoRxMqttCallback());
相关问题