samxiao
samxiao

Reputation: 2667

Mock file input as file path on Rspec

I have a question on how to use rspec to mock a file input. I have a following code for the class, but not exactly know a why to mock a file input. filepath is /path/to/the/file

I did my search on Google and usually turns out to be loading the actual file instead of mocking, but I'm actually looking the opposite where only mock, but not using the actual file.

module Service
  class Signing
    def initialize(filepath)
      @config = YAML.load_file(filepath)
      raise "Missing config file." if @config.nil?
    end

    def sign()      …
    end

    private
    def which()     …
    end

  end 
end

Is it possible to use EOF delimiter for this file input mocking?

file =  <<EOF
A_NAME: ABC
A_ALIAS: my_alias
EOF

Upvotes: 5

Views: 6387

Answers (2)

Nicholas Pufal
Nicholas Pufal

Reputation: 2205

If the idea is to put an expectation on something, I don't see much benefit on this approach of calling YAML.load to fake the return. YAML.load_file actually returns a hash, so instead of doing all that my suggestion would be to simply return a hash:

parsed_yaml = { 
  "somekey" => {
    "someotherkey" => "abc"
  } 
}

YAML.should_receive(:load_file).with(filepath).and_return(parsed_yaml)

As this is supposed to be a unit test and not an integration test, I think this would make more sense.

Upvotes: 3

Jim Stewart
Jim Stewart

Reputation: 17323

You could stub out YAML.load_file and return parsed YAML from your text, like this:

yaml_text = <<-EOF
  A_NAME: ABC
  A_ALIAS: my_alias
EOF
yaml = YAML.load(yaml_text)
filepath = "bogus_filename.yml"
YAML.stub(:load_file).with(filepath).and_return(yaml)

This doesn't quite stub out the file load itself, but to do that you'd have to make assumptions about what YAML.load_file does under the covers, and that's not a good idea. Since it's safe to assume that the YAML implementation is already tested, you can use the code above to replace the entire call with your parsed-from-text fixture.

If you want to test that the correct filename is passed to load_file, replace the stub with an expectation:

YAML.should_receive(:load_file).with(filepath).and_return(yaml)

Upvotes: 4

Related Questions