### Question:
StreamContext implements Context { @Override public final void addEvent(final String eventType, final Collection<Entry<String, String>> attributes, final ByteString data) throws InternalError { List<Attribute> attList = new ArrayList<>(); for (Map.Entry<String, String> entry : attributes) { Attribute att = Attribute.newBuilder().setKey(entry.getKey()).setValue(entry.getValue()).build(); attList.add(att); } Builder evtBuilder = Event.newBuilder().addAllAttributes(attList).setEventType(eventType); if (data != null) { evtBuilder.setData(data); } Event evt = evtBuilder.build(); TpEventAddRequest evtAddRequest = TpEventAddRequest.newBuilder().setContextId(contextId).setEvent(evt).build(); Future future = stream.send(Message.MessageType.TP_EVENT_ADD_REQUEST, evtAddRequest.toByteString()); TpEventAddResponse evtAddResponse = null; try { evtAddResponse = TpEventAddResponse.parseFrom(future.getResult(TIME_OUT)); } catch (InterruptedException iee) { throw new InternalError(iee.toString()); } catch (InvalidProtocolBufferException ipbe) { throw new InternalError(ipbe.toString()); } catch (ValidatorConnectionError vce) { throw new InternalError(vce.toString()); } catch (Exception e) { throw new InternalError(e.toString()); } if (evtAddResponse != null) { if (evtAddResponse.getStatus() == TpEventAddResponse.Status.ERROR) { throw new InternalError(String.format("Failed to add event %s, %s, %s", eventType, attributes, data)); } } } StreamContext(final Stream myStream, final String myContextId); @Override final Map<String, ByteString> getState(final Collection<String> addresses); @Override final Collection<String> setState(final Collection<java.util.Map.Entry<String, ByteString>> addressValuePairs); @Override final Collection<String> deleteState(final Collection<String> addresses); @Override final void addReceiptData(final ByteString data); @Override final void addEvent(final String eventType, final Collection<Entry<String, String>> attributes,
      final ByteString data);  }### Answer:
@Test public void testAddEvent() { Stream stream = mock(Stream.class); Context ctx = new StreamContext(stream, "test-context-id"); Map<String, String> testMap = new HashMap<>(); testMap.put("testKey1", "testValue1"); testMap.put("testKey2", "testValue2"); ByteString bs = ByteString.copyFromUtf8("testData"); FutureByteString okResponse = new FutureByteString("test-correlation-id"); okResponse .setResult(TpEventAddResponse.newBuilder().setStatus(TpEventAddResponse.Status.OK).build().toByteString()); FutureByteString errResponse = new FutureByteString("test-correlation-id"); errResponse .setResult(TpEventAddResponse.newBuilder().setStatus(TpEventAddResponse.Status.ERROR).build().toByteString()); FutureByteString garbageResponse = new FutureByteString("test-correlation-id"); garbageResponse.setResult(ByteString.copyFrom("something-garbage-like".getBytes())); try { when(stream.send(any(), any())).thenReturn(okResponse); ctx.addEvent("test-event", testMap.entrySet(), bs); } catch (InternalError exc) { fail("Happy path should not generate an InternalError"); } try { when(stream.send(any(), any())).thenReturn(garbageResponse); ctx.addEvent("test-event", testMap.entrySet(), bs); fail("An error should have been thrown since we responded with something wrong!"); } catch (InternalError ie) { } try { when(stream.send(any(), any())).thenReturn(errResponse); ctx.addEvent("test-event", testMap.entrySet(), bs); fail("An error should have been thrown since we responded with something wrong!"); } catch (InternalError ie) { } }