thoughtworks / pacto

Pacto settles disputes between JSON providers and consumers
thoughtworks.github.io/pacto
MIT License
401 stars 58 forks source link

Investigations are not run when stubbing a provider #168

Closed fishermand46 closed 9 years ago

fishermand46 commented 9 years ago

From the docs, I got the impression that if you were to do something like the following:

Pacto.validate!

contracts = Pacto.load_contracts(
  'spec/fixtures',
  'http://localhost:3000',
  :swagger
)
contracts.stub_providers

all requests made by your tests would be validated against the corresponding pacto contract, e.g. Pacto::Cops.perform_investigation request, response, self would be called. However, that method is only called when simulating consumers (done when testing providers).

maxlinc commented 9 years ago

That doesn't seem right. I definitely do investigations w/out simulating.

If you're using RSpec, try using these two Pacto matchers:

    expect(Pacto).to_not have_failed_investigations
    expect(Pacto).to_not have_unmatched_requests

I've run into issues sometimes where the host didn't quite match, e.g. if I loaded the contracts with 'http://localhost:3000' and the requests are sent to 'https://localhost:3000' (note the 's'). If that's happening then it should show up as an "unmatched request".

fishermand46 commented 9 years ago

Yep, I figured this one out yesterday after I opened this. Forget what I was doing wrong, but my requests are getting investigated now (and the rspec matchers are working great, too).

maxlinc commented 9 years ago

It'd probably make to have pacto raise an error on unmatched requests by default, but allow that to be turned off with an option like fail_on_unmatched_requests or allow_unmatched_request_if. I think most people using Pacto wouldn't intend to have tests w/ unmatched requests.

Also, if you have ideas for rspec matchers please create issues or send PRs. I think it's an area that is usefully but would be even more so with more matchers. It's also an area that's a little easier to change (compared to other parts where there's legacy vs swagger tech debt).

I would like to get away from expect(Pacto) and towards expect(investigation) or expect(investigations). The latter should work well with rspec 3's composable matches. Things like this should be possible:

investigations = with_pacto { call_your_code }
expect(investigations).to include(
  an_investigation_including(
    a_contract.with(name: 'My Contract')
    a_response.with(status: 200)
  ),
  an_investigation_including(
    a_contract.with(name: 'My Contract')
    a_response.with(status: 404)
  )
)