对我的组件进行JEST测试以在useEffect内引发异常

时间:2020-06-30 14:19:41

标签: reactjs jestjs react-testing-library

以下组件有效。但是,我想知道如何使用断言来测试它是否引发错误。

否,它使用上下文为我的项目提供值。但是我不确定这是否与这个问题有关,但是我还是想添加它。我希望无论该组件在上下文中的事实如何,都可以断言将要抛出的错误。

./ MyContext.jsx

$(document).ready(function() {
  "use strict";

  $('.form').submit(function(e) {
    e.preventDefault();

    // get the id of the form currently submitted
    let id = $(this).attr('id');

    $.ajax({
      url: "{{ url_for('home.index') }}",
      type: 'POST',
      cache: false,
      dataType: 'json',
      data: $('#' + id).serialize(),  // serialize the form
      success: function(data) {

        // console.log(data);


        // sanitize the form before processing the submitted fields
        if( ! data.errors.hasOwnProperty('r')){
          $('#' + id + ' input[name=r]').removeClass('is-invalid').next(".invalid-feedback").text('');
        }
        
        if( ! data.errors.hasOwnProperty('t')){
          $('#' + id + ' input[name=t]').removeClass('is-invalid').next(".invalid-feedback").text('');
        }
        
        if( ! data.errors.hasOwnProperty('u')){
          $('#' + id + ' input[name=u]').removeClass('is-invalid').next(".invalid-feedback").text('');
        }


        // @see https://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object
        if( ! jQuery.isEmptyObject(data.errors)) { // Errors (data.errors = {})

            console.log('Errors');
          
            if(data.errors.hasOwnProperty('r')){
              $('#' + id + ' input[name=r]').addClass('is-invalid').next(".invalid-feedback").text(data.errors['r']);
            }

            if(data.errors.hasOwnProperty('t')){
              $('#' + id + ' input[name=t]').addClass('is-invalid').next(".invalid-feedback").text(data.errors['t']);
            }

            if(data.errors.hasOwnProperty('u')){
              $('#' + id + ' input[name=u]').addClass('is-invalid').next(".invalid-feedback").text(data.errors['u']);
            }

          // update placeholder with the returned value
          $('#' + id + ' .placeholder').html('sin(r) * t + u = ' + data.s);


          } else { // Passed

          console.log('Passed');

          // get the submitted fields
          let r = $('#' + id + ' input[name=r]').val();
          let t = $('#' + id + ' input[name=t]').val();
          let u = $('#' + id + ' input[name=u]').val();

          // update placeholder with the returned value
          $('#' + id + ' .placeholder').html('sin(' + r + ') * ' + t + ' + ' + u + ' = ' + data.s);

          // reset fields
          $('#' + id + ' input[name=r]').val('');
          $('#' + id + ' input[name=t]').val('');
          $('#' + id + ' input[name=u]').val('');
        }
        
      }
    });
  });

});

然后在测试中

./ SomeComponent.spec.js

// ... generic imports left out for brevity
import request from './request';

const MyContext = createContext([{}, () => {}]);

const fetchList = async (url) => request(url);

const MyContextProvider = ({ children }) => {
  const [list, setList] = useState({
    fetchStatus: undefined,
    data: [],
  });

  const apiUrl = 'https://www.example.com/my-api/';

  useEffect(() => {
    setList({ fetchStatus: 'pending' });
    
    fetchList(apiUrl)
      .then((response) => {
        if (!response.success) {
          // 
          // this is what I want to test
          // 
          throw new Error(`The list fetch on ${apiUrl} was not successful.`);
        }
        setList({ data: response, fetchStatus: 'success' });
      })
      .catch(() => {
        setList({ fetchStatus: 'error' });
      });
  }, [apiUrl, setList]);

  return (
    <MyContext.Provider value={{ list }}>
      {children}
    </MyContext.Provider>
  );
};

export { MyContext, MyContextProvider };

我希望这可以解释我面临的问题。

1 个答案:

答案 0 :(得分:0)

该效果不会引发错误,但可以处理它。由于catch不使用捕获的错误,因此不会影响结果。

应该与未成功响应相同:

request.mockRejectedValue(new Error('whatever'));
await setup();
const { readSchedules } = await setup();
expect(readSchedules).toEqual({ fetchStatus: 'error' });