On Fri, Jun 26, 2015 at 3:02 AM, JSchlinker <[email protected]>
wrote:

> I am using Rspec to test a module that has an external dependency with the
> Internet.
> This is why I am trying to mock out the class that handles the actual
> access of the webpage when running my tests.
>
> My class "Snapshot" (that I want to test) accesses a webpage when it is
> requested and will save the html in a file when the hash of the content has
> changed.
> The filename should have a certain name according to the date/time and a
> running number.
> And there should be a log message when an error occours (e.g. no Internet
> or website down), containing the status code (e.g. 404).
>
> I made some basic tests, but now wanted to write a test integrating a
> couple of classes.
> The only thing that I would like to mock is the Internet part.
> As the snapshots are only generated when the html content changes I
> thought about the following approach:
>
> - Use timecop to fake a time and be able to check if the saved filename
> corresponds to this date/time
> - Mock the class "Internet" by specifying certain time spans in which the
> class should return a certain content
>
> My class under test looks like this:
>
> class Snapshot < ActiveRecord::Base
>
>      def self.grab_website(uri)
>          response, content = Internet.access_webpage(uri)
>          # code that calculates the hash, saves the content or generates
> an error log messages
>       end
>
> end
>
>
> My Rspec "preparation code" for mocking the class Internet looks like
> this:
>
> stub_const("Internet::WEBSITE_REPLIES", \
>         { "http://www.thiswebsiteisimportanttome.com"; => \
>                 [["2015-06-12 15:30", "website_Version_A.html"] ,\
>                  ["2015-06-14 18:00", "website_Version_B.html"] ,\
>                  ["2015-06-14 18:50", 404] ,\
>                  ["2015-06-14 19:00", "website_Version_C.html"] ,\
>                  ["2015-06-26 11:35", "website_Version_D.html"]] } )
>
>  allow(Internet).to receive(:access_webpage) do |uri|
>     time = Time.now
>     content = nil
>     response_code = 0               # We're not connected to the internet
>
>     if Internet::WEBSITE_REPLIES.has_key?(uri)
>         filename = nil
>         timetable = Internet::WEBSITE_REPLIES[uri]
>         timetable.each do |timepoint_situation|
>             timepoint = Time.parse(timepoint_situation[0])
>             if time > timepoint
>                 filename = timepoint_situation[1]
>             end
>         end
>         if (filename.nil?)
>             response_code = 0
>         elsif (filename.kind_of? Integer)
>             response_code = filename
>         else # filename is really a filename
>             content = File.read(filename)
>             response_code = 200
>         end
>     end
>     next response_code, content
> end
>
>
> And my actual test looks like this:
>
> first_time = Time.local(2015, 6, 12, 15, 35)
> second_time = Time.local(2015, 6, 14, 17, 00)
> third_time = Time.local(2015, 6, 14, 18, 05)
>
> uri = "http://www.thiswebsiteisimportanttome.com";
> Timecop.freeze(first_time) # Version A
> Snapshot.grab_website(uri)
>
> Timecop.freeze(second_time) # Version A (no changes)
> Snapshot.grab_website(uri)
>
> Timecop.freeze(third_time) # Version B
> Snapshot.grab_website(uri)
>
> snapshots = Snapshot.all
> expect(snapshots.size).to eq(2)
>
> snapshot = snapshots[0]
> expect(snapshot.time).to eq(first_time)
> expect(snapshot.hash).to eq("234092384EF")
> expect(snapshot.filename).to eq(...)
>
> snapshot = snapshots[1]
> expect(snapshot.time).to eq(third_time)
> expect(snapshot.hash).to eq("A8E92340213")
> expect(snapshot.filename).to eq(...)
>
> # work to do: check the log messages ...
>
>
> I have the feeling that there should be an easier way to do this.
> Especially because I can't imagine that I'm the only one that wants to
> test time dependent Website content.
> I am grateful for any suggestions!
>
> J.
>
> --
> You received this message because you are subscribed to the Google Groups
> "rspec" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/rspec/c1ed74fa-8f54-40ae-a6ba-ccfab2584bc1%40googlegroups.com
> <https://groups.google.com/d/msgid/rspec/c1ed74fa-8f54-40ae-a6ba-ccfab2584bc1%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

Take a look at VCR <https://relishapp.com/vcr/vcr/docs>. It is specifically
designed for when you are testing HTTP-dependent code.
​

-- 
You received this message because you are subscribed to the Google Groups 
"rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rspec/CADUxQmtt_vrq%2BRTbNHC%2BE%2BRTAubATaQrz26my7Dtd8FVKx0Yqw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to