function registerAndUnregisterAnimationWithMocks(delayType) {
  let timerCount = 0;

  replacer.set(delayType.prototype, 'start', () => {
    timerCount++;
  });
  replacer.set(delayType.prototype, 'stop', () => {
    timerCount--;
  });
  replacer.set(delayType.prototype, 'isActive', () => timerCount > 0);

  const forbiddenDelayType =
      delayType == AnimationDelay ? Delay : AnimationDelay;
  replacer.set(forbiddenDelayType.prototype, 'start', functions.error());
  replacer.set(forbiddenDelayType.prototype, 'stop', functions.error());
  replacer.set(forbiddenDelayType.prototype, 'isActive', functions.error());

  const anim = new Animation([0], [1], 1000);
  const anim2 = new Animation([0], [1], 1000);

  fxAnim.registerAnimation(anim);

  assertTrue(
      'Should contain the animation',
      googObject.containsValue(fxAnim.activeAnimations_, anim));
  assertEquals('Should have called start once', 1, timerCount);

  fxAnim.registerAnimation(anim2);

  assertEquals('Should not have called start again', 1, timerCount);

  // Add anim again.
  fxAnim.registerAnimation(anim);
  assertTrue(
      'Should contain the animation',
      googObject.containsValue(fxAnim.activeAnimations_, anim));
  assertEquals('Should not have called start again', 1, timerCount);

  fxAnim.unregisterAnimation(anim);
  assertFalse(
      'Should not contain the animation',
      googObject.containsValue(fxAnim.activeAnimations_, anim));
  assertEquals('clearTimeout should not have been called', 1, timerCount);

  fxAnim.unregisterAnimation(anim2);
  assertEquals('There should be no remaining timers', 0, timerCount);

  // Make sure we don't trigger setTimeout or setInterval.
  clock.tick(1000);
  fxAnim.cycleAnimations_(Date.now());

  assertEquals('There should be no remaining timers', 0, timerCount);

  anim.dispose();
  anim2.dispose();
}
@param {!Function} delayType The constructor for Delay or AnimationDelay.
    The methods will be mocked out.
@suppress {checkTypes,visibility} suppression added to enable type checking