### Question:
PickFirstLoadBalancer extends LoadBalancer { @Override public void handleResolvedAddressGroups( List<EquivalentAddressGroup> servers, Attributes attributes) { if (servers == null || servers.isEmpty()) { String errorMsg = "传入的servers参数不能为空"; logger.error(errorMsg); throw new RuntimeException(errorMsg); } EquivalentAddressGroup currentAddressGroup = servers.get(0); Subchannel subchannel = subchannels.get(currentAddressGroup); if (servers.size() > 1) { servers = servers.subList(0, 1); } if (subchannel == null) { subchannel = helper.createSubchannel(servers, Attributes.EMPTY); Subchannel oldValue = subchannels.putIfAbsent(currentAddressGroup, subchannel); if (oldValue == null) { helper.updateBalancingState(CONNECTING, new Picker(PickResult.withSubchannel(subchannel))); subchannel.requestConnection(); } else { subchannel = oldValue; helper.updateBalancingState(READY, new Picker(PickResult.withSubchannel(subchannel))); } } else { helper.updateBalancingState(READY, new Picker(PickResult.withSubchannel(subchannel))); } currentSubchannel = subchannel; } PickFirstLoadBalancer(Helper helper); @Override void handleResolvedAddressGroups(
      List<EquivalentAddressGroup> servers, Attributes attributes); @Override void handleNameResolutionError(Status error); @Override void handleSubchannelState(Subchannel subchannel, ConnectivityStateInfo stateInfo); @Override void shutdown(); @Override EquivalentAddressGroup getAddresses(); @Override void setAddress(EquivalentAddressGroup addressGroup); @Override void removeInvalidCacheSubchannels(Set<String> removeHostPorts);  }### Answer:
@Test public void pickAfterResolved() throws Exception { loadBalancer.handleResolvedAddressGroups(servers, affinity); verify(mockHelper).createSubchannel(eq(servers), attrsCaptor.capture()); verify(mockHelper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture()); verify(mockSubchannel).requestConnection(); assertEquals(pickerCaptor.getValue().pickSubchannel(mockArgs), pickerCaptor.getValue().pickSubchannel(mockArgs)); verifyNoMoreInteractions(mockHelper); }
@Test public void pickAfterResolvedAndUnchanged() throws Exception { loadBalancer.handleResolvedAddressGroups(servers, affinity); verify(mockSubchannel).requestConnection(); loadBalancer.handleResolvedAddressGroups(servers, affinity); verifyNoMoreInteractions(mockSubchannel); verify(mockHelper).createSubchannel(anyListOf(EquivalentAddressGroup.class), any(Attributes.class)); verify(mockHelper) .updateBalancingState(isA(ConnectivityState.class), isA(SubchannelPicker.class)); verify(mockHelper).updateSubchannelAddresses( eq(mockSubchannel), anyListOf(EquivalentAddressGroup.class)); verifyNoMoreInteractions(mockHelper); }
@Test public void pickAfterResolvedAndChanged() throws Exception { SocketAddress socketAddr = new FakeSocketAddress("newserver"); List<EquivalentAddressGroup> newServers = Lists.newArrayList(new EquivalentAddressGroup(socketAddr)); InOrder inOrder = inOrder(mockHelper); loadBalancer.handleResolvedAddressGroups(servers, affinity); inOrder.verify(mockHelper).createSubchannel(eq(servers), any(Attributes.class)); inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture()); verify(mockSubchannel).requestConnection(); assertEquals(mockSubchannel, pickerCaptor.getValue().pickSubchannel(mockArgs).getSubchannel()); loadBalancer.handleResolvedAddressGroups(newServers, affinity); inOrder.verify(mockHelper).updateSubchannelAddresses(eq(mockSubchannel), eq(newServers)); verifyNoMoreInteractions(mockSubchannel); verifyNoMoreInteractions(mockHelper); }