Answering myself, just in case someone else might find it useful:
I ended up with an example like this:
it 'renders config file with proper data on node ABC in environment XYZ' do
runner = ChefSpec::Runner.new
node_attr = JSON.parse(File.open('nodes/ABC.json'))
runner.node.consume_attributes(node_attr)
env_attr = JSON.parse(File.open('environments/XYZ.json'))
env = Chef::Environment.json_create(env_attr)
runner.node.stub(:chef_environment).and_return('XYZ')
Chef::Environment.stub(:load).and_return(env)
runner.converge('cookbook::recipe')
expect(runner).to render_file('/etc/cookbook.cfg').with_content('some data from ABC.json')
end
This works with the "monolithic chef repo" pattern, which I am using in this early phase of our chef adoption - in fact we are using chef-solo, but on a folder structure that tries to be compatible to a chef repo.
Moreover, I do not want to test for regressions during all the necessary restructuring without the speed of ChefSpec!