AbstractRuleBucket { protected void add(T rule) throws RuleException { T existingRule = rules.put(rule.getId(), rule); if (existingRule != null) { throw new RuleException("Cannot add rule with id '" + rule.getId() + "' from '" + rule.getSource().getId() + "' as it has already been defined in '" + existingRule.getSource().getId() + "'."); } }  int size(); Collection<T> getAll(); Set<String> getIds(); T getById(String id); List<T> match(String pattern); void add(B bucket);  }
@Test public void addWithCollectionFailIfAConceptIdIsSameConceptIdIsAlreadyInBucket() throws RuleException { Concept a = mock(Concept.class); when(a.getId()).thenReturn("a"); RuleSource sourceA = mock(RuleSource.class); doReturn("Source A").when(sourceA).getId(); doReturn(sourceA).when(a).getSource(); Concept duplicate = mock(Concept.class); when(duplicate.getId()).thenReturn("a"); RuleSource sourceDuplicate = mock(RuleSource.class); doReturn("Source Duplicate").when(sourceDuplicate).getId(); doReturn(sourceDuplicate).when(duplicate).getSource(); TestBucket existingBucket = new TestBucket(); existingBucket.add(a); TestBucket newBucket = new TestBucket(); newBucket.add(duplicate); assertThatThrownBy(() -> newBucket.add(existingBucket)).isInstanceOf(RuleException.class).hasMessageContaining("'Source A") .hasMessageContaining("'Source Duplicate'"); }