【发布时间】:2017-12-12 00:54:09
【问题描述】:
我无法测试抽象类实例中的方法。我已经尝试了几种方法,想知道是否可以这样做。抽象类的内容可以看下面的链接。
下面是我尝试测试上图中的案例的 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 显示的所有警报。但为此,我必须为抽象类创建一个实现,而不是使用匿名类。如以下链接所示
更新的单元测试:
@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);
}
}
【问题讨论】:
-
您在此处发布了多个测试,但您忘记向我们展示您要测试的抽象类和方法。另外,这些测试中的哪一个应该测试这个方法?
-
@alfasin 抽象类表示在可以通过上面的链接访问的图像中。 (雅可可班报告)。但是,如果您愿意,我可以通过完整放置课程内容来更新帖子。基本上,我想测试通过链接可用的图像中标记为红色的所有内容,特别是从第 50 行开始到第 70 行结束的方法。为此,我创建了测试方法:whenConnectionLostOccurs、whenConnectCompleteOccurs 和whenDeliveryComplete 分别发生。
-
在提问之前,您应该先学习一个简单的 Mockito 教程。
-
@tkruse 感谢您的评论,但您应该温和一点。我已经阅读了 Mockito。
标签: java junit mockito abstract-class anonymous-class