class_docstr: Base class for testing FXRateReader implementations.
  
  To test a new FXRateReader implementation, subclass from this base class
  and implement the ``reader`` property, returning an FXRateReader that uses
  the data stored in ``cls.fx_rates``.
code: def test_read_after_end_date(self):
      # Reads from **after** the end of our data, on the other hand, should
      # fail. We can always upper bound the relevant asofs that we're
      # interested in, and having fx rates forward-fill past the end of data
      # is confusing and takes a while to debug.
      for bad_date in (
          self.FX_RATES_END_DATE + pd.Timedelta("1 day"),
          self.FX_RATES_END_DATE + pd.Timedelta("1000 days"),
      ):
          for rate in self.FX_RATES_RATE_NAMES:
              quote = "USD"
              bases = np.array(["CAD"], dtype=object)
              dts = pd.DatetimeIndex([bad_date])
  
              result = self.reader.get_rates(rate, quote, bases, dts)
              assert_equal(result.shape, (1, 1))
              expected = self.get_expected_fx_rate_scalar(
                  rate,
                  quote,
                  "CAD",
                  self.FX_RATES_END_DATE,
              )
              assert_equal(expected, result[0, 0])
  
imports: import itertools
  import pandas
  import numpy
  from zipline.data.fx import DEFAULT_FX_RATE
  from zipline.testing.predicates import assert_equal
  import zipline.testing.fixtures
label_desc: Use image node_id 8 for calling the _FXReaderTestCase obj's underlying member method code with example usage: obj.test_read_after_end_date() without return types