@Test
public void testGetCacheKeyProjectValidatorCacheable() throws Exception {

  final Project project = mock(Project.class);
  final File projectDir = mock(File.class);
  final Props props = new Props();
  final ProjectValidatorCacheable mockValidatorCacheable = mock(ProjectValidatorCacheable.class);
  final ProjectValidator mockValidator = mock(ProjectValidator.class);
  final XmlValidatorManager manager = new XmlValidatorManager(props);
  // When we attempt to validate a project with our mock validator, return sampleReport
  final String cacheKey = "abc123";
  final String expectedResultingCacheKey = HashUtils.SHA1.getHashStr(cacheKey);
  when(mockValidatorCacheable.getCacheKey(project, projectDir, props)).thenReturn(cacheKey);
  Map<String, ProjectValidator> mockedValidators = new HashMap();
  // We add a non cacheable validator as well to ensure that it is ignored properly and no exceptions are thrown.
  mockedValidators.put("NORMAL", mockValidator);
  // Only this cacheable validator should contribute to the cacheKey
  mockedValidators.put("CACHEABLE", mockValidatorCacheable);
  // This is brittle and hacky, but we're directly setting the private validators field with our own
  Field validatorsField = manager.getClass().getDeclaredField("validators");
  validatorsField.setAccessible(true);
  FieldSetter.setField(manager, validatorsField, mockedValidators);
  // Make sure we get the cache key we expected (the SHA1 of the one cache key returned)
  assertEquals(expectedResultingCacheKey, manager.getCacheKey(project, projectDir, props));
}