I've read all of the relevant questions on this topic, and I realize this will probably be marked as a duplicate, but I simply cannot for the life of me figure out how to get this working.
I have this simple function that lazily loads elements:
export default function lazyLoad(targets, onIntersection) {
  const observer = new IntersectionObserver((entries, self) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        onIntersection(entry.target);
        self.unobserve(entry.target);
      }
    });
  });
  document.querySelectorAll(targets).forEach((target) => observer.observe(target));
  return observer;
}
Example usage:
lazyLoad('.lazy-img', (img) => {
  const pictureElement = img.parentElement;
  const source = pictureElement.querySelector('.lazy-source');
  source.srcset = source.getAttribute('data-srcset');
  img.src = img.getAttribute('data-src');
});
Now, I'm trying to test the lazyLoad function using jest, but I obviously need to mock IntersectionObserver since it's a browser API, not a native JavaScript one.
The following works for testing the observe method:
let observe;
let unobserve;
beforeEach(() => {
  observe = jest.fn();
  unobserve = jest.fn();
  window.IntersectionObserver = jest.fn(() => ({
    observe,
    unobserve,
  }));
});
describe('lazyLoad utility', () => {
  it('calls observe on each target', () => {
    for (let i = 0; i < 3; i++) {
      const target = document.createElement('img');
      target.className = 'lazy-img';
      document.body.appendChild(target);
    }
    lazyLoad(
      '.lazy-img',
      jest.fn(() => {})
    );
    expect(observe).toHaveBeenCalledTimes(3);
  });
});
But I also want to test the .isIntersecting logic, where the callback fires... Except I don't know how to do that. How can I test intersections with jest?