### Question:
FundsAndRefundsAggregator { public List<UserFundsDto> aggregate(final List<FundsByFunderDto> fundsByFunder) { return fundsByFunder.stream() .collect(Collectors.groupingBy(funds -> funds.getFunderAddress().toLowerCase() + funds.getFunderUserId(), Collectors.mapping(mapToUserFundDto(), Collectors.reducing(mergeFundsAndRefunds())))) .values() .stream() .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toList()); }  List<UserFundsDto> aggregate(final List<FundsByFunderDto> fundsByFunder);  }### Answer:
@Test public void aggregate() { final String funder1UserId = "dgfhj"; final String funder1Address = "0xFHDsad"; final String funder2UserId = "jghf"; final String funder2Address = "0xtrdkl"; final String funder3UserId = "hfg"; final String funder3Address = "0xeytru"; final FundsByFunderDto fundsByFunderDto1 = buildFundsByFunderDto(funder1UserId, funder1Address, "10", "20"); final FundsByFunderDto fundsByFunderDto2 = buildFundsByFunderDto(funder2UserId, funder2Address, null, "-30"); final FundsByFunderDto fundsByFunderDto3 = buildFundsByFunderDto(funder3UserId, funder3Address, "65", null); final FundsByFunderDto fundsByFunderDto4 = buildFundsByFunderDto(funder1UserId, funder1Address.toUpperCase(), "-10", "-10"); final FundsByFunderDto fundsByFunderDto5 = buildFundsByFunderDto(funder2UserId, funder2Address, null, "60"); final FundsByFunderDto fundsByFunderDto6 = buildFundsByFunderDto(funder3UserId, funder3Address, "-35", null); final List<UserFundsDto> result = fundsAndRefundsAggregator.aggregate(Arrays.asList(fundsByFunderDto1, fundsByFunderDto2, fundsByFunderDto3, fundsByFunderDto4, fundsByFunderDto5, fundsByFunderDto6)); assertThat(result).contains(buildUserFundsDtoFrom(fundsByFunderDto1, fundsByFunderDto4), buildUserFundsDtoFrom(fundsByFunderDto5, fundsByFunderDto2), buildUserFundsDtoFrom(fundsByFunderDto3, fundsByFunderDto6)); }