Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Testing Services Effectively

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

Testing Services Effectively

Avatar for Alberto Leal

Alberto Leal

August 04, 2014
Tweet

More Decks by Alberto Leal

Other Decks in Programming

Transcript

  1. Connection: keep-alive Content-Length: 1466 Content-Type: application/json; Date: Sat, 02 Aug

    2014 19:42:38 GMT ETag: W/"5ba-70348105" { "cars": [ { "created": "2014-07-25T19:27:56.919Z", "id": "53d2afbc7165355f0eaf79da", "modified": "2014-07-25T19:27:56.919Z", "name": "Ferrari" }, { "created": "2014-07-25T19:27:56.874Z", "id": "53d2afbc7165355f0eaf79d9", "modified": "2014-07-25T19:27:56.874Z", "name": "Porshe" } ] } Request Response http://api.example.com/cars
  2. Connection: keep-alive Content-Length: 1466 Content-Type: application/json; Date: Sat, 02 Aug

    2014 19:42:38 GMT ETag: W/"5ba-70348105" { "cars": [ { "created": "2014-07-25T19:27:56.919Z", "id": "53d2afbc7165355f0eaf79da", "modified": "2014-07-25T19:27:56.919Z", "name": "Ferrari" }, { "created": "2014-07-25T19:27:56.874Z", "id": "53d2afbc7165355f0eaf79d9", "modified": "2014-07-25T19:27:56.874Z", "name": "Porshe" } ] } headers
  3. Connection: keep-alive Content-Length: 1466 Content-Type: application/json; Date: Sat, 02 Aug

    2014 19:42:38 GMT ETag: W/"5ba-70348105" { "cars": [ { "created": "2014-07-25T19:27:56.919Z", "id": "53d2afbc7165355f0eaf79da", "modified": "2014-07-25T19:27:56.919Z", "name": "Ferrari" }, { "created": "2014-07-25T19:27:56.874Z", "id": "53d2afbc7165355f0eaf79d9", "modified": "2014-07-25T19:27:56.874Z", "name": "Porshe" } ] } body
  4. Failures: ! 1) Car Service should retrieve all cars Failure/Error:

    response = RestClient.get ‘api.example.com/cars' SocketError: getaddrinfo: nodename nor servname provided, or not known # ./test_spec.rb:12:in `block (2 levels) in <top (required)>' ! Finished in 0.02436 seconds (files took 0.81924 seconds to load) 1 example, 1 failure ! Failed examples: ! rspec ./test_spec.rb:11 # External Service should retrieve all cars
  5. require 'webmock/rspec' require 'rest_client' ! describe 'Car Service’ do it

    'should retrieve all cars' do response = RestClient.get ‘api.example.com/cars' expect(response).to be_an_instance_of(String) end end
  6. ------------------------------ FAIL: 1 PASS: 0 PENDING: 0 ------------------------------ Finished in

    0.04571 seconds [Car Service] - should retrieve all cars Real HTTP connections are disabled. Unregistered request: GET http:// api.example.com/cars with headers {'Accept'=>'*/*; q=0.5, application/ xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'}You can stub this request with the following snippet:stub_request(:get, “http:// api.example.com/cars”). with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User- Agent'=>'Ruby'}). to_return(:status => 200, :body => "", :headers => {})
  7. require 'webmock/rspec' require 'rest_client' ! WebMock.allow_net_connect! ! describe 'Car Service'

    do it 'should retrieve all cars' do response = RestClient.get ‘api.example.com/cars' expect(response).to be_an_instance_of(String) end end
  8. require 'webmock/rspec' require 'rest_client' ! # WebMock.allow_net_connect! ! describe 'Car

    Service' do before :all do stub_request(:get, ‘api.example.com/cars') .to_return(status: 200, headers: {}, body: 'This is a mock.') end ! it 'should retrieve all cars' do response = RestClient.get ‘http://api.example.com/cars' expect(response).to eq(‘This is a mock.') end end
  9. ENV["RAILS_ENV"] ||= 'test' require File.expand_path("../../config/environment", __FILE__) require 'rspec/rails' require 'rspec/autorun'

    ! RSpec.configure do |config| config.mock_with :rspec config.infer_base_class_for_anonymous_controllers = false config.order = "random" ! #Configuring VCR gem config.around(:each, :vcr) do |example| opts = example.metadata.slice(:record, :match_requests_on).except(:example_group) VCR.use_cassette(example.metadata[:cassette_name], opts) { example.call } end end
  10. describe Car do ... describe '.all' do it 'should retrieve

    all available cars', :vcr, cassette_name: ‘cars/all’ do cars = Car.all expect(cars).to be_an_instance_of Array expect(cars).to have(2).items end end ! ... end
  11. class MyServiceProviderClient include HTTParty base_uri 'http://my-service' ! def get_something name

    = JSON.parse(self.class.get("/something").body)['name'] Something.new(name) end end Client
  12. require 'pact/consumer/rspec' ! Pact.service_consumer "My Service Consumer" do has_pact_with "My

    Service Provider" do mock_service :my_service_provider do port 1234 end end end Mock Server
  13. describe MyServiceProviderClient, pact: true do ! before do # Configure

    your client to point to the stub service on localhost using the port you have specified MyServiceProviderClient.base_uri 'localhost:1234' end ! subject { MyServiceProviderClient.new } ! describe "get_something" do ! before do my_service_provider.given("something exists"). upon_receiving("a request for something").with(method: :get, path: '/something'). will_respond_with( status: 200, headers: {'Content-Type' => 'application/json'}, body: {name: 'A small something'} ) end ! it "returns a Something" do expect(subject.get_something).to eq(Something.new('A small something')) end ! end ! end