惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threatpost
博客园 - 叶小钗
T
The Blog of Author Tim Ferriss
Recent Announcements
Recent Announcements
D
DataBreaches.Net
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
罗磊的独立博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
N
Netflix TechBlog - Medium
Microsoft Azure Blog
Microsoft Azure Blog
Microsoft Security Blog
Microsoft Security Blog
B
Blog
U
Unit 42
有赞技术团队
有赞技术团队
博客园 - 聂微东
GbyAI
GbyAI
宝玉的分享
宝玉的分享
F
Full Disclosure
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MyScale Blog
MyScale Blog
Jina AI
Jina AI
Martin Fowler
Martin Fowler
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
D
Docker
P
Proofpoint News Feed
A
About on SuperTechFans
I
InfoQ
博客园 - 【当耐特】
C
Check Point Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy & Cybersecurity Law Blog
T
Threat Research - Cisco Blogs
Y
Y Combinator Blog
Project Zero
Project Zero
WordPress大学
WordPress大学
小众软件
小众软件
AWS News Blog
AWS News Blog
博客园 - 司徒正美
T
The Exploit Database - CXSecurity.com
L
LINUX DO - 热门话题
I
Intezer
Engineering at Meta
Engineering at Meta
C
CXSECURITY Database RSS Feed - CXSecurity.com
J
Java Code Geeks
T
Tenable Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Last Week in AI
Last Week in AI
C
CERT Recently Published Vulnerability Notes

Chip Cullen

The need for importance, and AI: Chip Cullen An updated Colorosetta: Chip Cullen The Return of the Font Combinator!: Chip Cullen Changing the number of an item in an ordered list: Chip Cullen My pizza dough recipe as of May 2025: Chip Cullen Gonna try to be a bit more personal: Chip Cullen How I built dynamic social media images in Eleventy using Cloudinary: Chip Cullen My current approach to AI : Chip Cullen Lessons Learned Surviving a Major Product Launch: Chip Cullen How to Build a Drop Down Menu with Modern CSS: Chip Cullen How to stop page scrolling when you have an open dialog element: Chip Cullen Distraction Driven Development: Chip Cullen How I learned to code: the art of letting go: Chip Cullen In praise of the switch statement: Chip Cullen Project stuck? Think about how you’re breaking it down & question everything: Chip Cullen So how did the onboarding experiment go?: Chip Cullen Ideas for an Onboarding Checklist: Chip Cullen I really like Post Mortems: Chip Cullen Raise Red Flags Early: Chip Cullen How to mock fetch requests in React Testing Librarty tests: Chip Cullen Running a Structured Meeting: Chip Cullen Adding the View Transitions API to my personal site: Chip Cullen A Lightweight Way to Read GraphQL Data: Chip Cullen How to make a color changing favicon: Chip Cullen Using a Pros/Cons list to help navigate technical discussions: Chip Cullen How to use variable fonts from Google Fonts: Chip Cullen A new website: now on Eleventy!: Chip Cullen How to Truncate Type at More Than One Line with Just CSS: Chip Cullen Colorosetta: the VS Code Extension!: Chip Cullen Using CSS Custom Properties and Logical Properties Together: Chip Cullen Browser Dev Tools: Element Inspector Popover: Chip Cullen The Link with rel=preload is a Seperate Thing: Chip Cullen How to have Dark & Light Mode Images that also works with User Choice: Chip Cullen Don’t use Viewport Units for Font Size on their own: Chip Cullen A little known Media Query: Aspect Ratio: Chip Cullen Meta thinking: Managing Decisions: Chip Cullen Give Your To-Do's Context: Chip Cullen Say What the Impact is when Reporting Issues: Chip Cullen Firefighting 101: How to Manage Breakages: Chip Cullen How to Deal With Large Pieces of Technical Debt: Chip Cullen Make Your Request Clear: Chip Cullen Analytics events, HTML classes, and protecting against refactoring: Chip Cullen How We Removed jQuery from a large app: Chip Cullen New tool: ColoRosetta: Chip Cullen What width and height attributes should you use with responsive images?: Chip Cullen Django 3.1 gotcha: Referrer Policy has a new default, and it might break iframes and links: Chip Cullen A Javascript Component Pattern: Chip Cullen CSS min(), max() and clamp() Functions: Chip Cullen Pointer Events and Inline Elements in Chrome: Chip Cullen Resolving a github repo and a new Create React App: Chip Cullen How to POST *Data* with the Fetch API: Chip Cullen The Contrast Triangle: Chip Cullen Advice on interviewing for Junior Developers: Chip Cullen Life Lessons Learned From Running a Marathon: How to do something really hard: Chip Cullen A (Brief) intro to Search Engine Structured Data: Chip Cullen Javascript Fallback Values on Variables and Booleans - a hard lesson: Chip Cullen Alfred Tip: Quickly Access Common URLs: Chip Cullen Responsive Images in Hugo - by Laura Kalbag: Chip Cullen Making a Gatsby Site with Multiple Content Types: Chip Cullen How to Create and Use Fixtures in Cypress Tests: Chip Cullen Fixing the 'Bad Interpreter' Error from AWS and Python 3.7: Chip Cullen Creating a Canonical Tag in a Django Template: Chip Cullen Responsive spacing with viewport and ch units: Chip Cullen Welcome to my New Design - 2019: Chip Cullen Django Templates: Block and If statements don’t work like you might expect: Chip Cullen Books I Read in 2018: Chip Cullen Lifehack: 4 ways to help tame common email noise: Chip Cullen How to make better Pull Requests: Adding Steps to Test: Chip Cullen The unsung develpment tool: Spreadsheets: Chip Cullen Troubleshooting Adding and Removing EventListeners: with Arguments, Debounced, and in a React Class: Chip Cullen Migrating From Wordpress to Hugo: Chip Cullen Background Repeat and its Possibilities: Chip Cullen Getting Started With Front End Tests: a Mindset: Chip Cullen Migrating a Blog - An Opportunity for a Content Inventory: Chip Cullen Moving to Hugo: Chip Cullen JavaScript events: .target vs .currentTarget: Chip Cullen Things I wish I knew when starting with Python: Chip Cullen Leading Ampersands for modifiers in Sass: An anti-pattern: Chip Cullen How to get rid of the "You have mail" message in your terminal: Chip Cullen Why three typefaces rule the web, and what you can do about it: Chip Cullen You shouldn't worry about Section 508 - it's Section 504: Chip Cullen Looping Video Backgrounds: pointers and pitfalls: Chip Cullen How to “preview” a click event tag in the Google Tag Manager console: Chip Cullen Moving on from a technology, or: life after Drupal: Chip Cullen Don’t be a dumb developer: Chip Cullen Two level breadcrumbs with CSS :only-child: Chip Cullen Simplicity comes with experience: Chip Cullen Do the least amount possible: Chip Cullen SVGs vs. Icon Fonts: Two points in favor of Icon Fonts: Chip Cullen Accessible links without underlines: Chip Cullen The Strategic Job Hunt: Chip Cullen Surviving Getting Laid Off: Chip Cullen How to structure your typography in Sass: Chip Cullen Layer Cake: A Responsive Design Layout Pattern: Chip Cullen Creativity is yet to come in Web Design: Chip Cullen Front End Testing with Wraith: A Step by Step Recipe: Chip Cullen Where to begin? How I start a visual design for the web: Chip Cullen If you could only have five Google Fonts: Chip Cullen Why SVG is so cool (or: what happens when you're late to the party on something): Chip Cullen How to apply classes to elements with CKEditor 4, in Drupal 7: Chip Cullen
How to Fake the Window Object in Jest and Enzyme: Chip Cullen
2018-09-24 · via Chip Cullen

I was struggling with writing a test the other day for a React component that was mostly a stateless component, but it did read two properties of the window object and made some decisions based on that.

The problem is that Jest makes use of jsdom which doesn't provide the window object. I googled and googled and struggled with many suggestions around problems that weren't exactly what I was trying to solve. Most of the solutions I found were people trying to mock window functions. What I needed was a fake window object itself, and one that didn't involve hacking my jest.setup.js file.

A coworker (yet another one who is much smarter than me) suggested that I could solve this by making a lightweight use of Dependency Injection. In the context of this article, I'll define that as setting external data points as optional parameters to your function, so that you can inject them in your tests more easily, and you can side-step the vagaries of your test runner.

I will be using React components in this blog post, but there is no reason the concept can't transfer to other JavaScript implementations.

Let's say the component looked something like this:

// our-component.js
class ourComponent extends Component {
  render() {
    const { data } = this.props;

    const windowData = window.windowData;

    let title = data.title;

    // altering the title variable if the window object has windowData
    if (windowData) {
      title = windowData;
    }

    return <div className="our-component">{title}</div>;
  }
}

ReactPassportTooltip.propTypes = {
  data: PropTypes.object.isRequired
};

export default ourComponent;

The problem comes when we try to write a unit test (in my case, using Jest and Enzyme) for this component. We need to be able to supply window.windowData for our tests.

The solution for this situation, for me, was the dependency injection that my coworker suggested. It's really just a fancy term to allow for faking some data by making a function parameter optional. In this case we "inject" window by altering the original function like so:

// our-component.js

class ourComponent extends Component {
  render() {
    // depWindowData - 'dep' just signifies it's a dependecy prop as a convention
    const { data, depWindowData } = this.props;

    // testing for depWindowData OR window.windowData
    const windowData = depWindowData || window.windowData;

    let title = data.title;

    // altering the title variable if the there is windowData
    if (windowData) {
      title = windowData;
    }

    return <div className="our-component">{title}</div>;
  }
}

ReactPassportTooltip.propTypes = {
  data: PropTypes.object.isRequired
};

export default ourComponent;

This allows us to then write our test something like this:

// our-component.test.js
import React from "react";
import { shallow } from "enzyme";

import ourComponent from "./our-component";

function setup() {
  const props = {
    data: {
      title: "Example Title"
    }
  };

  const enzymeWrapper = shallow(<ourComponent {...props} />);

  return { props, enzymeWrapper };
}

describe("ourComponent Test", () => {
  const { enzymeWrapper } = setup();

  test("ourComponent Should Render with the default title", () => {
    // the first test will be for the default prop-based title
    expect(enzymeWrapper.find(".our-component").text()).toBe("Example Title");
  });

  test("ourComponent Should Render with a different title", () => {
    // using .setProps we 'inject' depWindowData
    enzymeWrapper.setProps({ depWindowData: "Window based title" });
    // and now we get a new text string
    expect(enzymeWrapper.find(".our-component").text()).toBe(
      "Window based title"
    );
  });
});

By modifying our original function, we've made it easy for a test to pass along an optional dependency. This makes the tests much simpler, as we're not having to resort to crazy methods of inject or faking a window object.