开玩笑不会自动嘲笑常见的js模块 [英] Jest not auto mocking common js modules

查看:111
本文介绍了开玩笑不会自动嘲笑常见的js模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用Jest测试Flux和React应用程序.

I am trying to wrap my head around testing Flux and React applications using Jest.

我开始使用 Scotch.io教程作为我的起点,并将创建一个完整的测试套件,以获取有关如何构建我的第一个实际的React和Flux应用程序的知识.

I started using Scotch.io tutorial as my starting point and will be creating a full test suite to gain knowledge in how to structure my first real react and flux app.

您可以在github上找到我的代码看看我在哪里.

不能运行的测试是

jest.dontMock('../FluxProduct');

var React
  , TestUtils
  , FluxProduct
  , FluxCartActions;

describe('FluxProduct', function() {


  var SAMPLE = {
    product: {
      id: '1',
      name: 'Name',
      image: 'image.png',
      description: 'this description',
      variants: [
        {
          sku: '123',
          type: 'First',
          price: 1.99,
          inventory: 1
        },
        {
          sku: '456',
          type: 'Second',
          price: 2.99,
          inventory: 3
        },
        {
          sku: '789',
          type: 'Third',
          price: 3.99,
          inventory: 2
        }
      ]
    },
  };


  function getElement(product, className)
  {
    return product.getDOMNode().getElementsByClassName(className)[0];
  }

  function getElementByTag(product, tagName)
  {
    return product.getDOMNode().getElementsByTagName(tagName)[0];
  }

  function selectIsActive(select, text)
  {
    for( var i = 0; i < select.options.length; i++)
    {
      if (select.options[i].textContent == text)
      {
        return true
      }
    }
    return false;
  }

  beforeEach(function(){
    React = require('react/addons')
    , TestUtils = React.addons.TestUtils
    , FluxProduct = require('../FluxProduct')
    , FluxCartActions = require('../../actions/FluxCartActions');
  });

  it('should have the display all of the fields', function() {
    var cartItems = [];
    var selected = SAMPLE.product.variants[1];
    var product = TestUtils.renderIntoDocument(
      <FluxProduct selected={selected} product={SAMPLE.product} cartitems={cartItems} />
    );

    expect(getElement(product, 'name').textContent).toEqual(SAMPLE.product.name);
    expect(getElement(product, 'description').textContent).toEqual(SAMPLE.product.description);
    expect(getElement(product, 'price').textContent).toEqual('Price: $' + selected.price);
    expect(selectIsActive(getElementByTag(product, 'select'), selected.type)).toEqual(true);
  });

  it('should allow to add another variant', function() {
    var cartItems = [];
    var selected = SAMPLE.product.variants[1];
    var targetVariantIndex = 2;
    var targetVariant = SAMPLE.product.variants[targetVariantIndex];
    var product = TestUtils.renderIntoDocument(
      <FluxProduct selected={selected} product={SAMPLE.product} cartitems={cartItems} />
    );
    var selectElement = getElementByTag(product, 'select');
    var addToCartBtn = getElementByTag(product, 'select');

    TestUtils.Simulate.change(selectElement, { target: { value: targetVariantIndex } });

    expect(selectIsActive(selectElement, targetVariant.type)).toEqual(true);

    TestUtils.Simulate.click(addToCartBtn);

    expect(FluxCartActions.addToCart.mock.calls.length).toBe(1);
    expect(FluxCartActions.addToCart.mock.calls[0][0]).toBe(targetVariant.sku);
    expect(FluxCartActions.addToCart.mock.calls[0][0]).toBe({
      name: targetVariant.name,
      type: targetVariant.type,
      price: targetVariant.price
    });
  });
});

它在第100行返回"TypeError:无法读取未定义的属性'calls'".

It comes back with "TypeError: Cannot read property 'calls' of undefined" on line 100.

当我注销FluxActions时,似乎并没有对其进行自动模拟,这就是未定义模拟并且访问calls属性引发错误的原因.

When I log out FluxActions it seems that it is not being automocked, which is the reason mock is undefined and accessing the calls property is throwing the error.

fyi:Jest需要Node 0.10,不能在0.12上运行

fyi: Jest requires Node 0.10, does not run on 0.12

有用的参考文件:

FluxProduct.jsx

var React = require('react');
var FluxCartActions = require('../actions/FluxCartActions');

// Flux product view
var FluxProduct = React.createClass({

  // Add item to cart via Actions
  addToCart: function(event){
    var sku = this.props.selected.sku;
    var update = {
      name: this.props.product.name,
      type: this.props.selected.type,
      price: this.props.selected.price
    }
    FluxCartActions.addToCart(sku, update);
    FluxCartActions.updateCartVisible(true);
  },

  // Select product variation via Actions
  selectVariant: function(event){
    FluxCartActions.selectProduct(event.target.value);
  },

  // Render product View
  render: function() {
    var ats = (this.props.selected.sku in this.props.cartitems) ?
      this.props.selected.inventory - this.props.cartitems[this.props.selected.sku].quantity :
      this.props.selected.inventory;
    return (
      <div className="flux-product">
        <img src={'assets/' + this.props.product.image}/>
        <div className="flux-product-detail">
          <h1 className="name">{this.props.product.name}</h1>
          <p className="description">{this.props.product.description}</p>
          <p className="price">Price: ${this.props.selected.price}</p>
          <select onChange={this.selectVariant}>
            {this.props.product.variants.map(function(variant, index){
              return (
                <option key={index} value={index}>{variant.type}</option>
              )
            })}
          </select>
          <button type="button" onClick={this.addToCart} disabled={ats  > 0 ? '' : 'disabled'}>
            {ats > 0 ? 'Add To Cart' : 'Sold Out'}
          </button>
        </div>
      </div>
    );
  },

});

module.exports = FluxProduct;

FluxCartActions.js

var AppDispatcher = require('../dispatcher/AppDispatcher');
var FluxCartConstants = require('../constants/FluxCartConstants');

// Define action methods
var FluxCartActions = {

  // Receive inital product data
  receiveProduct: function(data) {
    AppDispatcher.handleAction({
      actionType: FluxCartConstants.RECEIVE_DATA,
      data: data
    })
  },

  // Set currently selected product variation
  selectProduct: function(index) {
    AppDispatcher.handleAction({
      actionType: FluxCartConstants.SELECT_PRODUCT,
      data: index
    })
  },

  // Add item to cart
  addToCart: function(sku, update) {
    AppDispatcher.handleAction({
      actionType: FluxCartConstants.CART_ADD,
      sku: sku,
      update: update
    })
  },

  // Remove item from cart
  removeFromCart: function(sku) {
    AppDispatcher.handleAction({
      actionType: FluxCartConstants.CART_REMOVE,
      sku: sku
    })
  },

  // Update cart visibility status
  updateCartVisible: function(cartVisible) {
    AppDispatcher.handleAction({
      actionType: FluxCartConstants.CART_VISIBLE,
      cartVisible: cartVisible
    })
  }

};

module.exports = FluxCartActions;

这是我的package.json文件:

Here is my package.json file:

{
  "name": "flux-pricing",
  "version": "0.0.1",
  "description": "Pricing component with flux",
  "main": "app/assets/javascripts/cart.js",
  "dependencies": {
    "flux": "^2.0.0",
    "react": "^0.12.0",
    "underscore": "^1.7.0"
  },
  "devDependencies": {
    "browserify": "~>6.3.0",
    "envify": "~3.0.0",
    "jest-cli": "^0.4.0",
    "react-tools": "^0.12.2",
    "reactify": "^1.0",
    "watchify": "~2.1.0"
  },
  "scripts": {
    "start": "watchify -o app/assets/javascripts/app.js -v -d .",
    "build": "browserify . | uglifyjs -cm > app/assets/javascripts/app.min.js",
    "test": "jest"
  },
  "jest": {
    "rootDir": "app/assets/javascripts",
    "scriptPreprocessor": "<rootDir>/__tests__/preprocessor.js",
    "testFileExtensions": [
      "js",
      "jsx"
    ],
    "unmockedModulePathPatterns": ["react"],
    "testPathIgnorePatterns": [
      "preprocessor.js",
      "node_modules"
    ]
  },
  "browserify": {
    "transform": [
      "reactify",
      "envify"
    ]
  }
}

我通过在应用目录中运行npm test来运行测试.

I run tests by running npm test in the app directory.

推荐答案

我认为问题可能是您需要beforeEach中的模拟,这可能会取消执行jest的auto- genMockFunction为你做.我只是更改了一些编写的测试,以相同的方式要求使用beforeEach的模块,并且它们也坏了,就好像这些函数不是模拟的一样.

I think the issue could be that you are requiring the mocks in beforeEach, which could be un-doing the auto-genMockFunction that jest does for you. I just changed some tests I had written to require the modules in the beforeEach the same way, and they broke as well, as if the functions weren't mocks.

尝试在测试之外只要求依赖项.

Try just requiring the dependencies once outside the tests.

var React = require('react/addons')
    , TestUtils = React.addons.TestUtils
    , FluxProduct = require('../FluxProduct')
    , FluxCartActions = require('../../actions/FluxCartActions');

describe(...);

想必您正在执行此操作以重置"模拟,以便测试不会产生副作用,但是如果jest尚未为您处理,我会感到惊讶.

Presumably, you are doing this to "reset" the mocks so that tests don't have side-effects, but I'd be surprised if jest doesn't already handle that for you.

这篇关于开玩笑不会自动嘲笑常见的js模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆