test_class.declarator: directory = mock(Directory.class)
test_class.modifier: private
test_class.original_string: private Directory directory = mock(Directory.class);
test_class.type: Directory
test_class.var_name: directory
test_class.declarator: firstInvoker = mock(Invoker.class)
test_class.modifier: private
test_class.original_string: private Invoker firstInvoker = mock(Invoker.class);
test_class.type: Invoker
test_class.var_name: firstInvoker
test_class.declarator: secondInvoker = mock(Invoker.class)
test_class.modifier: private
test_class.original_string: private Invoker secondInvoker = mock(Invoker.class);
test_class.type: Invoker
test_class.var_name: secondInvoker
test_class.declarator: invocation = mock(Invocation.class)
test_class.modifier: private
test_class.original_string: private Invocation invocation = mock(Invocation.class);
test_class.type: Invocation
test_class.var_name: invocation
test_class.declarator: mergeableClusterInvoker
test_class.modifier: private
test_class.original_string: private MergeableClusterInvoker<MenuService> mergeableClusterInvoker;
test_class.type: MergeableClusterInvoker<MenuService>
test_class.var_name: mergeableClusterInvoker
test_class.declarator: list1 = {"10", "11", "12"}
test_class.modifier: private
test_class.original_string: private String[] list1 = {"10", "11", "12"};
test_class.type: String[]
test_class.var_name: list1
test_class.declarator: list2 = {"20", "21", "22"}
test_class.modifier: private
test_class.original_string: private String[] list2 = {"20", "21", "22"};
test_class.type: String[]
test_class.var_name: list2
test_class.declarator: list3 = {"23", "24", "25"}
test_class.modifier: private
test_class.original_string: private String[] list3 = {"23", "24", "25"};
test_class.type: String[]
test_class.var_name: list3
test_class.declarator: list4 = {"30", "31", "32"}
test_class.modifier: private
test_class.original_string: private String[] list4 = {"30", "31", "32"};
test_class.type: String[]
test_class.var_name: list4
test_class.declarator: firstMenuMap = new HashMap<String, List<String>>() {
          {
              put("1", Arrays.asList(list1));
              put("2", Arrays.asList(list2));
          }
      }
test_class.modifier: private
test_class.original_string: private Map<String, List<String>> firstMenuMap = new HashMap<String, List<String>>() {
          {
              put("1", Arrays.asList(list1));
              put("2", Arrays.asList(list2));
          }
      };
test_class.type: Map<String, List<String>>
test_class.var_name: firstMenuMap
test_class.declarator: secondMenuMap = new HashMap<String, List<String>>() {
          {
              put("2", Arrays.asList(list3));
              put("3", Arrays.asList(list4));
          }
      }
test_class.modifier: private
test_class.original_string: private Map<String, List<String>> secondMenuMap = new HashMap<String, List<String>>() {
          {
              put("2", Arrays.asList(list3));
              put("3", Arrays.asList(list4));
          }
      };
test_class.type: Map<String, List<String>>
test_class.var_name: secondMenuMap
test_class.declarator: firstMenu = new Menu(firstMenuMap)
test_class.modifier: private
test_class.original_string: private Menu firstMenu = new Menu(firstMenuMap);
test_class.type: Menu
test_class.var_name: firstMenu
test_class.declarator: secondMenu = new Menu(secondMenuMap)
test_class.modifier: private
test_class.original_string: private Menu secondMenu = new Menu(secondMenuMap);
test_class.type: Menu
test_class.var_name: secondMenu
test_class.declarator: url = URL.valueOf("test://test/" + MenuService.class.getName())
test_class.modifier: private
test_class.original_string: private URL url = URL.valueOf("test://test/" + MenuService.class.getName());
test_class.type: URL
test_class.var_name: url
test_class.file: dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvokerTest.java
test_class.identifier: MergeableClusterInvokerTest
test_case.body: @Test
      public void testGetMenuSuccessfully() throws Exception {
  
          // setup
          url = url.addParameter(MERGER_KEY, ".merge");
  
          given(invocation.getMethodName()).willReturn("getMenu");
          given(invocation.getParameterTypes()).willReturn(new Class<?>[]{});
          given(invocation.getArguments()).willReturn(new Object[]{});
          given(invocation.getObjectAttachments()).willReturn(new HashMap<>())
                  ;
          given(invocation.getInvoker()).willReturn(firstInvoker);
  
          firstInvoker = (Invoker) Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[]{Invoker.class}, (proxy, method, args) -> {
              if ("getUrl".equals(method.getName())) {
                  return url.addParameter(GROUP_KEY, "first");
              }
              if ("getInterface".equals(method.getName())) {
                  return MenuService.class;
              }
              if ("invoke".equals(method.getName())) {
                  return AsyncRpcResult.newDefaultAsyncResult(firstMenu, invocation);
              }
              return null;
          });
  
          secondInvoker = (Invoker) Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[]{Invoker.class}, (proxy, method, args) -> {
              if ("getUrl".equals(method.getName())) {
                  return url.addParameter(GROUP_KEY, "second");
              }
              if ("getInterface".equals(method.getName())) {
                  return MenuService.class;
              }
              if ("invoke".equals(method.getName())) {
                  return AsyncRpcResult.newDefaultAsyncResult(secondMenu, invocation);
              }
              return null;
          });
  
          given(directory.list(invocation)).willReturn(new ArrayList() {
  
              {
                  add(firstInvoker);
                  add(secondInvoker);
              }
          });
          given(directory.getUrl()).willReturn(url);
          given(directory.getConsumerUrl()).willReturn(url);
          given(directory.getConsumerUrl()).willReturn(url);
          given(directory.getInterface()).willReturn(MenuService.class);
  
          mergeableClusterInvoker = new MergeableClusterInvoker<MenuService>(directory);
  
          // invoke
          Result result = mergeableClusterInvoker.invoke(invocation);
          Assertions.assertTrue(result.getValue() instanceof Menu);
          Menu menu = (Menu) result.getValue();
          Map<String, List<String>> expected = new HashMap<String, List<String>>();
          merge(expected, firstMenuMap);
          merge(expected, secondMenuMap);
          assertEquals(expected.keySet(), menu.getMenus().keySet());
          for (Map.Entry<String, List<String>> entry : expected.entrySet()) {
              // FIXME: cannot guarantee the sequence of the merge result, check implementation in
              // MergeableClusterInvoker#invoke
              List<String> values1 = new ArrayList<String>(entry.getValue());
              List<String> values2 = new ArrayList<String>(menu.getMenus().get(entry.getKey()));
              Collections.sort(values1);
              Collections.sort(values2);
              assertEquals(values1, values2);
          }
      }
test_case.class_method_signature: MergeableClusterInvokerTest.testGetMenuSuccessfully()
test_case.full_signature: @Test public void testGetMenuSuccessfully()
test_case.identifier: testGetMenuSuccessfully
test_case.invocations: addParameter willReturn given getMethodName willReturn given getParameterTypes willReturn given getArguments willReturn given getObjectAttachments willReturn given getInvoker newProxyInstance getClassLoader getClass equals getName addParameter equals getName equals getName newDefaultAsyncResult newProxyInstance getClassLoader getClass equals getName addParameter equals getName equals getName newDefaultAsyncResult willReturn given list add add willReturn given getUrl willReturn given getConsumerUrl willReturn given getConsumerUrl willReturn given getInterface invoke assertTrue getValue getValue merge merge assertEquals keySet keySet getMenus entrySet getValue get getMenus getKey sort sort assertEquals
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void testGetMenuSuccessfully()
focal_class.declarator: log = LoggerFactory.getLogger(MergeableClusterInvoker.class)
focal_class.modifier: private static final
focal_class.original_string: private static final Logger log = LoggerFactory.getLogger(MergeableClusterInvoker.class);
focal_class.type: Logger
focal_class.var_name: log
focal_class.file: dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java
focal_class.identifier: MergeableClusterInvoker
focal_class.class_method_signature: MergeableClusterInvoker.MergeableClusterInvoker(Directory<T> directory)
focal_class.full_signature: public  MergeableClusterInvoker(Directory<T> directory)
focal_class.identifier: MergeableClusterInvoker
focal_class.modifiers: public
focal_class.parameters: (Directory<T> directory)
focal_class.signature:  MergeableClusterInvoker(Directory<T> directory)
focal_class.class_method_signature: MergeableClusterInvoker.doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)
focal_class.full_signature: @Override protected Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)
focal_class.identifier: doInvoke
focal_class.modifiers: @Override protected
focal_class.parameters: (Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)
focal_class.return: Result
focal_class.signature: Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)
focal_class.class_method_signature: MergeableClusterInvoker.getInterface()
focal_class.full_signature: @Override public Class<T> getInterface()
focal_class.identifier: getInterface
focal_class.modifiers: @Override public
focal_class.parameters: ()
focal_class.return: Class<T>
focal_class.signature: Class<T> getInterface()
focal_class.class_method_signature: MergeableClusterInvoker.isAvailable()
focal_class.full_signature: @Override public boolean isAvailable()
focal_class.identifier: isAvailable
focal_class.modifiers: @Override public
focal_class.parameters: ()
focal_class.return: boolean
focal_class.signature: boolean isAvailable()
focal_class.class_method_signature: MergeableClusterInvoker.destroy()
focal_class.full_signature: @Override public void destroy()
focal_class.identifier: destroy
focal_class.modifiers: @Override public
focal_class.parameters: ()
focal_class.return: void
focal_class.signature: void destroy()
focal_class.class_method_signature: MergeableClusterInvoker.getGroupDescFromServiceKey(String key)
focal_class.full_signature: private String getGroupDescFromServiceKey(String key)
focal_class.identifier: getGroupDescFromServiceKey
focal_class.modifiers: private
focal_class.parameters: (String key)
focal_class.return: String
focal_class.signature: String getGroupDescFromServiceKey(String key)
focal_class.superclass: extends AbstractClusterInvoker<T>
focal_method.body: @Override
      public Class<T> getInterface() {
          return directory.getInterface();
      }
focal_method.class_method_signature: MergeableClusterInvoker.getInterface()
focal_method.full_signature: @Override public Class<T> getInterface()
focal_method.identifier: getInterface
focal_method.invocations: getInterface
focal_method.modifiers: @Override public
focal_method.parameters: ()
focal_method.return: Class<T>
focal_method.signature: Class<T> getInterface()