Giter Site home page Giter Site logo

Comments (28)

zhaotai avatar zhaotai commented on August 19, 2024 7

Well, the solution of @miracle2k can not solve my problem directly because the image name they mock is just the same to the actual image name.

But as we all known, if you require an image without 2x or 3x postfix just like abc.png instead of [email protected], react-native will also require the right one automatically depending on the active device. And that's why I confronted this problem and all above didn't solve it.

So inspired by the code of @miracle2k , I replaced the file with request directly because in my situation there is no abc.png at all and the function _resolveFilename will throw a can not find module error.
At last, my code is below

const m = require('module');
const originalLoader = m._load;

m._load = function hookedLoader(request, parent, isMain) {
  if (request.match(/.jpeg|.jpg|.png$/)) {
    return { uri: request };
  }

  return originalLoader(request, parent, isMain);
};

I haven't tried the mockery solution because I use mocha and enzyme as my unit test library and I have a setup.js file to handle all the mocks whatever the native modules or third-party modules. And the best solution for me is to write these code in the same file.

from react-native-mock.

miracle2k avatar miracle2k commented on August 19, 2024 5

I didn't want to mock all image paths manually, so I made this hook:

var m = require('module');
var originalLoader = m._load;

m._load = function hookedLoader(request, parent, isMain) {
  var file = m._resolveFilename(request, parent);
  if (file.match(/.jpeg|.jpg|.png$/))
    return {uri: file};

  return originalLoader(request, parent, isMain);
}

from react-native-mock.

sibelius avatar sibelius commented on August 19, 2024 2

for react-native-router-flux to run I've used this commands with Mockery on testHelper.js

import mockery from 'mockery';

mockery.enable();

mockery.registerMock('./menu_burger.png', 'burguer');
mockery.registerMock('./back_chevron.png', 'chevron');

from react-native-mock.

varmais avatar varmais commented on August 19, 2024 2

I'm running my tests with mocha and found mocha-image-compiler useful when testing components which require images. See my example repository for examples: react-native-unit-tests.

It comes with downside though: You will get a prop type warning when running the tests, but I'll rather take the warning than leave components untested.

from react-native-mock.

Jeiwan avatar Jeiwan commented on August 19, 2024 1

I used https://github.com/mfncooper/mockery to solve the same issue. It allows you to globally mock require, so you can do:

mockery.enable();
mockery.registerMock('../Images/Logo/some_image.png', 'nice image');

In your tests and this will affect all the files that require '../Images/Logo/some_image.png'. require('../Images/Logo/some_image.png') then will return 'nice image'.

Another similar tool is https://github.com/thlorenz/proxyquire

from react-native-mock.

RealOrangeOne avatar RealOrangeOne commented on August 19, 2024 1

@slamus The best way to mock an image objects source would be to pass it something it's expecting.

mockery.registerMock('../img/myimage.png', {{ uri: 'myimage.png' }});

The image doesnt have to exist or anything, but it's a better way of mocking it than just passing in a random value

from react-native-mock.

ryyppy avatar ryyppy commented on August 19, 2024 1

Funny that this discussion just arised.. I was working on the same mocking problem independently yesterday and came to a very similar (non-working) solution as @zhaotai ... this will save me many hours of debugging the node module system... it's also not as intrusive as mockery.

I know mockery and I used it for other products myself.. the thing is, before I would ever use it, I might as well just use jest instead ... because jest does practically the exact same thing more efficiently and with first level React-Native support...

from react-native-mock.

GantMan avatar GantMan commented on August 19, 2024

thanks!

from react-native-mock.

lelandrichardson avatar lelandrichardson commented on August 19, 2024

This is a great question. Perhaps we could build a method where you can pass it a glob string for images and it will automatically register them as image objects in the require cache.

Open to hear anyone else's suggestions as well...

from react-native-mock.

iyawnis avatar iyawnis commented on August 19, 2024

If I use mockery tests are working, but instead of a dir error I was getting the following:

Unexpected character '�' (1:0)
  SyntaxError: test/images/reactNe.png: Unexpected character '�' (1:0)
  > 1 | �PNG
      | ^
    2 | 
    3 | 
    4 | IHDR3�W�SgAMA��
                       �asRGB��� cHRMz&�����u0�`:�p��Q<bKGD�������  pHYsHHF�k>n�IDATx���u�V�ڇ���A���������X����BQ��cwca�b���
      at Parser.pp.raise (node_modules/babylon/index.js:1425:13)

from react-native-mock.

Jeiwan avatar Jeiwan commented on August 19, 2024

@latusaki you cannot require an image in JS. React Native seems to have some kind of a wrapper around require that catches all paths pointing to an image and processes them in a correct way. If you mock image requiring, you should just return a string that somehow relates to the required file (its name, for example), so you could test this string in a component and check that a correct file was required.

from react-native-mock.

jdebbink avatar jdebbink commented on August 19, 2024

@Jeiwan
How are you getting mockery to work? I am getting the same error as @latusaki .

In my module I have:
<Image source={require('./images/temp.png')}/>

In my test file I have:

var mockery = require('mockery');

mockery.enable();
mockery.registerMock('./images/temp.png', 'temp.png');
const Temp = require('../Temp.js');
mockery.disable();

describe('<Temp/>', () => {
  ...
});

from react-native-mock.

iyawnis avatar iyawnis commented on August 19, 2024

I guess you have tried not disabling mockery?

from react-native-mock.

jdebbink avatar jdebbink commented on August 19, 2024

@latusaki That worked, thanks!

from react-native-mock.

iyawnis avatar iyawnis commented on August 19, 2024

If I remember correct the effect of mockery does not persist between test cases, so I have just added it like this:

  before(() => {
    mockery.enable();
    mockery.registerMock('../../../images/logo-pink.png', 'logo-ping.png');
  });

from react-native-mock.

slamus avatar slamus commented on August 19, 2024

Hey Guys,

Thanks for your help I've been able to fix the require problem.
However, none of your solutions worked for me because required propType for Image.source is either number or shape (?)
So, my solution was this:

import mockery from "mockery";

mockery.enable();
mockery.registerMock('../img/myimage.png', 0)

from react-native-mock.

Sh3rawi avatar Sh3rawi commented on August 19, 2024

I ran into the same issue today, and what i did was the following (im using jest):
node_modules/babel-jest/src/index.js:

  process(src, filename) {
    if (babel.util.canCompile(filename)) {
      return babel.transform(src, {
        auxiliaryCommentBefore: ' istanbul ignore next ',
        filename,
        presets: [jestPreset],
        retainLines: true,
      }).code;
    }
    return src;
  },

but it can't compile images, so it returns the source (which is the image itself).
All my images are pngs, so i added the following check:

    if (filename.match(/\.png$/)) {
      const w = filename.match(/(.+\/)(.+png$)/)[2];
      const source = `module.exports = '${w}';`;
      return babel.transform(source, {
        auxiliaryCommentBefore: ' istanbul ignore next ',
        filename,
        presets: [jestPreset],
        retainLines: true,
      }).code;
    }

So i return a string for every image require i have, which is very convenient for testing:
i shallow render the component, get a reference to the image and check the source prop string to be the right image name.

from react-native-mock.

benjick avatar benjick commented on August 19, 2024

Hey, trying your solutions here, but not sure what I'm doing wrong.

test/Button.js

import React, { View, Text, StyleSheet } from 'react-native';
import mockery from "mockery";
import { shallow } from 'enzyme';
import { expect } from 'chai';

mockery.enable();
mockery.registerMock('../src/Theme/assets/closeWhite.png', { uri: 'myimage.png' }); //

import { CloseButton } from '../src';

describe('<CloseButton />', () => {
  it('should render stuff', () => {
    const wrapper = shallow(<CloseButton />);
    expect(wrapper.length).to.equal(1);
  });
});

/*
/node_modules/babel-core/lib/transformation/file/index.js:556
      throw err;
      ^

/src/Theme/assets/closeWhite.png: Unexpected character '�' (1:0)
> 1 | �PNG
    | ^
*/

from react-native-mock.

RealOrangeOne avatar RealOrangeOne commented on August 19, 2024

@benjick Can you post the source of the CloseButton component too? Remember the first arguement of mockery should be the exact string you try and require, not a relative path to the file

from react-native-mock.

RealOrangeOne avatar RealOrangeOne commented on August 19, 2024

@miracle2k oohh that's really nice! Could you submit that as a PR? Maybe putting it in mock.js?

from react-native-mock.

sibelius avatar sibelius commented on August 19, 2024

@miracle2k how can I use this hook with react-native-mock?

from react-native-mock.

sibelius avatar sibelius commented on August 19, 2024

hey @slamus can u provide a repo with your solution?

from react-native-mock.

sibelius avatar sibelius commented on August 19, 2024

@RealOrangeOne I think we should create a gitter room to discuss solutions for these issues

from react-native-mock.

RealOrangeOne avatar RealOrangeOne commented on August 19, 2024

I was thinking about doing something like that, let me look into it further before I create something

from react-native-mock.

RealOrangeOne avatar RealOrangeOne commented on August 19, 2024

@varmais Wow, that's really nice! Although yes the prop warning would get annoying. It's definately much easier than using mockery! We could fork that library and add it in, conditionally obviously.

from react-native-mock.

GantMan avatar GantMan commented on August 19, 2024

Just tested the @zhaotai and @miracle2k solution. Works fantastic. Going to be moving this into our default AVA tests for the Ignite project. Now everyone who creates a new Ignite starter will have their work right away. I'll be sure to make more shout outs in the release notes. Thanks!

from react-native-mock.

GantMan avatar GantMan commented on August 19, 2024

O and I"m closing this ticket :) cheers!

from react-native-mock.

icynoangel avatar icynoangel commented on August 19, 2024

Hmm... I have added the hookLoader for images in my mocha setup file, I don't get the error about images anymore, but I do have the following error:

TypeError: Plugin 1 specified in "/node_modules/react-native-router-flux/node_modules/react-native-experimental-navigation/package.json" was expected to return a function but returned "undefined"

Anyone got this error?

from react-native-mock.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.