23
Bag o’ Tricks: Unit Testing Anton ’tony’ Bangratz https://abangratz.github.com/ @tony_xpro [email protected] 2012-01-18

Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Embed Size (px)

Citation preview

Page 1: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Bag o’ Tricks: Unit Testing

Anton ’tony’ Bangratzhttps://abangratz.github.com/

@tony_xpro

[email protected]

2012-01-18

Page 2: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Introduction

Page 3: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

The Art of Testing

Page 4: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Not (only) Rails

Page 5: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

One Method, One Purpose

Consider:

class TitanClass

.

.

.

def doIt(*args)

args[:external_sources].each do |source|

args[:data_gatherers] do |gatherer|

gatherer.doIt(source)

end

end

processed_data = []

current_gatherers.each do |gatherer|

processed_data << process_data(gatherer)

end

reports = {}

processed_data.each do |data|

reports[data.id] = Report.new(data)

end

ReportPrinter.print_all(reports)

end

end

Page 6: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

One Method, One Purpose

Test:

require ’spec_helper’

describe TitanClass do

it "should do everything" do

source = double(Source)

gatherer = double(Gatherer)

args = {external_sources: [source],

data_gatherers: [gatherer]}

processed = double("ProcessedData")

subject.should_receive(process_data)

.with(gatherer).and_return(processed)

report = double(Report)

Report.should_receive(:new).with(processed).

and_return(report)

ReportPrinter.should_receive(:print_all).with([report])

subject.doIt(args)

end

end

Page 7: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

One Method, One Purpose

Test:

require ’spec_helper’

describe TitanClass do

it "should do everything" do

source = double(Source)

gatherer = double(Gatherer)

args = {external_sources: [source],

data_gatherers: [gatherer]}

processed = double("ProcessedData")

subject.should_receive(process_data)

.with(gatherer).and_return(processed)

# Yikes, a stub on the subject under test!

report = double(Report)

Report.should_receive(:new).with(processed).

and_return(report)

# Stubbing ".new" is rarely a good idea

ReportPrinter.should_receive(:print_all).with([report])

# Huh. We know that a ReportPrinter prints reports,

# but that’s more than we actually should know ...

subject.doIt(args)

end

end

Page 8: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

One Test, One Assertion

Page 9: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Example

describe SmartClass do

it "invokes the data gatherer" do

data_gatherer = double(DataGatherer)

source = double(Source)

data_gatherer.should_receive(gather).with(source))

# Our only assertion!

subject.data_gatherer = data_gatherer # DI for the win

subject.gather_from_source(source)

end end

...

class SmartClass

attr_accessor :data_gatherer

def gather_from_source(source)

data_gatherer_gather(source)

end

end

Page 10: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Mocking and Stubbing

Page 11: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Testing Modules

Page 12: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Example

class TestSmartModule

include SmartModule

end

describe SmartModule do

subject { TestSmartModule.new }

it "does something" do

subject.something.should ...

end

end

Page 13: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Testing IO

Page 14: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Well, Rails

Page 15: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Anonymous Controllers

Page 16: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Example

describe SomeClass, type: ’controller’ do

controller(ApplicationControllerOrSubClass) do

def index

... # do something

end

end

it "makes something happen" do

... # assert something happens

get :index

end

end

Page 17: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Testing Models?

Page 18: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Another Layer

Page 19: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

TDD

Page 20: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Frameworks

Page 21: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

MiniTest or RSpec?

Page 22: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

That’s all, folks.

Page 23: Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Thanks

• Stephan Kamper

• Lisa Crispin

• Elisabeth Hendricks

• Michael Bolton

• Avdi Grimm

• Steve Klabnik

• Jeremy Evans

• Martin Gamsjager

• Robert C. Martin (Uncle Bob)

• Andreas Kopecky

• Jurgen Strobel

• Andreas Tiefenthaler

• Michael Kohl

• Floor Drees

• Friends and colleagues that inspired me