使用Jest更改元素大小

18
我组件里有以下代码
var rect = ReactDOM.findDOMNode(this).getBoundingClientRect();

我使用d3js在组件中渲染图形。但是当我运行测试时,所有rect字段都等于0,因此没有任何svg标签。在浏览器中运行console.log(rect)的输出如下:

ClientRect {top: 89, right: 808, bottom: 689, left: 8, width: 800…}

而在运行测试时:

{ bottom: 0, height: 0, left: 0, right: 0, top: 0, width: 0 }

那么有没有办法设置元素的大小呢?

3个回答

50

我的解决方案是模拟getBoundingClientRect函数(我目前正在使用jest 16.0.1)。

describe('Mock `getBoundingClientRect`', () => {
    beforeEach(() => {
        Element.prototype.getBoundingClientRect = jest.fn(() => {
            return {
                width: 120,
                height: 120,
                top: 0,
                left: 0,
                bottom: 0,
                right: 0,
            }
        });
    });
    it('should mock `getBoundingClientRect`', () => {
        const element = document.createElement('span');
        const rect = element.getBoundingClientRect();
        expect(rect.width).toEqual(120);
    });

});


1
谢谢你的回答。我只是想知道,“Element”这个词从哪里来的? - Wayne Chiu
据我所知,jest使用jsdom来模拟DOM类(例如Element等)-https://github.com/tmpvar/jsdom - alunyov
4
请注意,如果您有多个描述符针对 getBoundingClientRect 具有特定情况,您需要为该特定描述符再次设置此模拟值,因为全局对象原型正在被改变。 - Roland Jegorov

2

别忘了把 getBoundingClientRect 的原始值放回去,因为更改它可能会影响其他测试。

此外,不需要在 beforeEach 中执行此操作:beforeAll 就可以了。

describe("Mock `getBoundingClientRect`", () => {
  let boundingClientRect;

  const originalGetBoundingClientRect = Element.prototype.getBoundingClientRect;

  beforeAll(() => {
    Element.prototype.getBoundingClientRect = () => boundingClientRect;
  });

  afterAll(() => {
    Element.prototype.getBoundingClientRect = originalGetBoundingClientRect;
  });

  it("should mock `getBoundingClientRect`", () => {
    const element = document.createElement("div");
    boundingClientRect = new DOMRect(0, 0, 120, 120);
    const rect = element.getBoundingClientRect();
    expect(rect.width).toEqual(120);
  });
});


我从这个答案中得到了灵感。


0

现有的答案模拟了Element.prototype.getBoundingClientRect。这将影响你测试中所有DOM元素的显示大小。

如果您预先知道关心的元素,可以在单个元素上模拟getBoundingClientRect。这不会影响其他元素的显示大小。如果您希望同一测试中的两个元素具有不同的大小,则需要按此方法执行。

describe("Mock `getBoundingClientRect` on a single element", () => {
  it("should mock `getBoundingClientRect`", () => {
    const myElement = document.createElement("div");
    myElement.getBoundingClientRect = jest.fn(() => 
      new DOMRect(0, 0, 120, 120);
    );
    const rect = element.getBoundingClientRect();
    expect(rect.width).toEqual(120);
  });
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接