3

I'm having a weird issue where I'm testing a controller that has a procedure that uses caching. The test is failing, but if I do a binding.pry inside the method that does the caching, the test passes.

example of the method containing the caching and the binding.pry:

def method_example:
  data = Rails.cache.fetch(cache_key) do
    ProcedureService.new(params).generate
  end

  binding.pry

  data
end

Example of the test:

  it "reverts record amount" do
    expect(record.amount).to eq((original_amount + other_amount).to_d)
  end

The caching is done via redis_store.

When done in the development environment, it works fine. What I don't understand is why it is failing but passing when adding a stopper? It seems it could be something about the time it takes to fetch the cache

UPDATE

Using sleep, instead of binding.pry also makes the test pass, so I can assume this is a timing issue. What is the problem exactly? and how could I manage it?

FutoRicky
  • 903
  • 2
  • 9
  • 22

1 Answers1

0

I think this has to do with cashing enabled or not enabled in your tests:

you can set expectations like this with the current implementation in your example method:

expect(Rails).to receive_massage_change(:cashe, :fetch).and_return(expected_value)

you can also inject the ProcedureService instance to the method and set expectation on it like this:

procedure_service_instance = instance_double('ProcedureService', generate: some_value_you_want_to_be_returned)

expect(procedure_service_instance).to receive(:generate)

if you make your example method like this:

def method_example
  data = Constant.fetch_from_cashe(cache_key)
  procedure_service.generate
  data
end

then you could git rid of receive_message_chain expectation and use:

expect(Constant).to receive(:fetch_from_cashe).with(cashe_key).and_return(expected_value)
expect_any_instance_of(ProcedureService).to receive(:generate){ some_fake_return_value }

also you can enable caching in your tests, check these links: link1, link2, link3

I do not know exactly where, and how your original is written, but based on the example method you provided, I think setting expectation on the methods that get sent would do the trick. and note that your goal is not to test rails cashing but to test that your code does use it as you want.

Abdullah Fadhel
  • 294
  • 2
  • 9