title: Jest: mock out Expo releaseChannels
body: <p>Been trying trying out a lot of things but without luck. I'm trying to test out my configuration for different release channels in expo.</p>
  <p>My latest attempt looks like this:</p>
  <pre class="lang-js prettyprint-override"><code>import * as Updates from 'expo-updates'
  import { Platform } from 'react-native'
  
  export const BUILD_PROFILES = ['local', 'development', 'preview', 'production'] as const
  type BuildProfile = typeof BUILD_PROFILES[number]
  
  export default function Configuration() {
    type EnvironmentVariables = {
      API_URL: string
    }
    console.log({ releaseChannel: Updates.releaseChannel })
    switch (Updates.releaseChannel as BuildProfile) {
      case 'local': {
        const env: EnvironmentVariables = {
          API_URL: Platform.OS === 'android' ? 'http://10.0.2.2:3001' : 'http://localhost:3001',
        }
        return env
      }
  
      case 'development': {
        const env: EnvironmentVariables = {
          API_URL: 'http://test.company.com',
        }
  
        return env
      }
  
      default: {
        const env: EnvironmentVariables = {
          API_URL: 'http://test.company.com',
        }
  
        return env
      }
    }
  }
  </code></pre>
  <pre class="lang-js prettyprint-override"><code>import { Platform } from 'react-native'
  
  import * as CONFIG from '.'
  
  const easJson = require('~/eas.json')
  
  describe('Config.ts', () =&gt; {
    afterEach(() =&gt; {
      jest.restoreAllMocks()
    })
  
    it('has all the build profiles in eas[&quot;build&quot;]', () =&gt; {
      Object.keys(easJson.build).forEach((key) =&gt; {
        expect(CONFIG.BUILD_PROFILES).toContain(key)
      })
    })
  
    describe('Development', () =&gt; {
      describe('Locally (on the MacBook)', () =&gt; {
        beforeEach(() =&gt; {
          jest.spyOn('expo-updates', 'releaseChannel', 'get').mockReturnValue('local')
        })
  
        describe('iPhone Simulator', () =&gt; {
          beforeEach(() =&gt; {
            jest.mock('react-native/Libraries/Utilities/Platform', () =&gt; ({
              OS: 'ios',
              select: () =&gt; null,
            }))
            Platform.OS = 'ios'
          })
  
          it('has API_URL with localhost', () =&gt; {
            expect(CONFIG.default().API_URL).toEqual('http://localhost:3001')
          })
        })
  
        describe('Android Emulator', () =&gt; {
          beforeEach(() =&gt; {
            jest.mock('react-native/Libraries/Utilities/Platform', () =&gt; ({
              OS: 'android',
              select: () =&gt; null,
            }))
            Platform.OS = 'android'
          })
  
          it('has API_URL WITHOUT localhost', () =&gt; {
            expect(CONFIG.default().API_URL).toEqual('http://10.0.2.2:3001')
          })
        })
  
        describe('web browser', () =&gt; {
          beforeEach(() =&gt; {
            jest.mock('react-native/Libraries/Utilities/Platform', () =&gt; ({
              OS: 'web',
              select: () =&gt; null,
            }))
            Platform.OS = 'web'
          })
  
          it('has API_URL with localhost', () =&gt; {
            expect(CONFIG.default().API_URL).toEqual('http://localhost:3001')
          })
        })
      })
    })
  })
  
  </code></pre>
  <p>But it seems to still just do</p>
  <pre class="lang-sh prettyprint-override"><code>console.log
      { releaseChannel: 'default' }
  </code></pre>
  <hr />
  <p>My jest configuration looks like:</p>
  <pre class="lang-js prettyprint-override"><code>/** @type {import('@jest/types').Config.InitialOptions} */
  module.exports = {
    preset: 'jest-expo',
    rootDir: '../../',
    setupFilesAfterEnv: ['./test/jest/setup.js'], // Setup life-cycle for jest tests.
    automock: false, // it means it will not run the __mocks__ folder by default (so we have to manually mock it in each test or in the setup.js file)
    clearMocks: true, // https://marek-rozmus.medium.com/jest-mock-and-spy-mockclear-vs-mockreset-vs-mockrestore-f52395581950
    moduleDirectories: ['node_modules'],
    modulePathIgnorePatterns: ['&lt;rootDir&gt;/.fttemplates/*'],
    moduleNameMapper: {
      // scape out non-supported NodeJS files
      '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
        '&lt;rootDir&gt;/test/jest/assetsTransformer.js',
      '\\.(css|scss|less)$': '&lt;rootDir&gt;/test/jest/assetsTransformer.js',
    },
    transformIgnorePatterns: [
      // transpiling non-transpiled packages
      'node_modules/(?!(jest-)?react-native|@react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base)',
    ],
    collectCoverage: true,
    collectCoverageFrom: [
      '**/*.{js,jsx,ts,tsx}',
      // Don't include the following
      '!.*.{js,jsx,ts,tsx}',
      '!**/coverage/**',
      '!**/node_modules/**',
      '!**/.fttemplates/**',
      '!**/babel.config.{js,ts}',
      '!**/jest.config.{js,ts}',
      '!**/jest.setup.{js,ts}',
      '!**/prettier.config.{js,ts}',
    ],
  }
  </code></pre>
  <hr />
  <h1>Update</h1>
  <p>found out that putting it at the top does mock it out</p>
  <pre class="lang-js prettyprint-override"><code>jest.mock('expo-updates', () =&gt; ({
    releaseChannel: 'local',
  }))
  
  describe('Config.ts', () =&gt; {
    afterEach(() =&gt; {
      jest.restoreAllMocks()
    })
  
    ...
  </code></pre>
  <p>but then I'm not able to change it from <code>'local'</code> to <code>'development'</code> for my other test cases</p>