I don't know exactly what is going on in your `subscription_cancelled_at`
method but generally if you are trying to run tests with time involved you
want to use something like Timecop (https://github.com/travisjeffery/timecop)
or, if you are using Rails, the Rails time helpers (
https://api.rubyonrails.org/v6.1.3/classes/ActiveSupport/Testing/TimeHelpers.html).
This will allow you to change the time at will and to freeze time so that
you do not see small differences that are most likely due to the time it
takes to run your code.

Regards,

Joe

On Thu, 25 Feb 2021 at 18:58, Jack Royal-Gordon <jac...@pobox.com> wrote:

> I have the following examples:
>
>   describe "#subscription_cancelled_at" do
>     let!(:user) { FactoryBot.create(:user, stripe_id: 'stripe') }
>     let!(:stripe_customer) { Stripe::Customer.new }
>     let!(:past_date) { 2.weeks.ago }
>     let!(:future_date) { 2.weeks.from_now }
>     let!(:subscription) { build_deep_struct(status: 'active',
> cancel_at_period_end: false, canceled_at: nil, current_period_end:
> future_date) }
>
>     it 'returns nil if there is no subscription' do
>       allow(user).to receive(:stripe_customer).and_return(nil)
>       expect(user).to receive(:stripe_customer)
>       expect(stripe_customer).to_not receive(:subscriptions)
>       expect(user.subscription_cancelled_at).to be_nil
>     end
>
>     it "returns canceled_at if it is populated" do
>       subscription.canceled_at = past_date
>       allow(user).to receive(:stripe_customer).and_return(stripe_customer)
>       allow(stripe_customer).to
> receive(:subscriptions).and_return([subscription])
>       expect(user).to receive(:stripe_customer)
>       expect(stripe_customer).to receive(:subscriptions)
>       expect(user.subscription_cancelled_at.utc).to eq past_date
>     end
>
>     it "returns current_period_end if subscription will cancel at period
> end" do
>       subscription.cancel_at_period_end = true
>       allow(user).to receive(:stripe_customer).and_return(stripe_customer)
>       allow(stripe_customer).to
> receive(:subscriptions).and_return([subscription])
>       expect(user).to receive(:stripe_customer)
>       expect(stripe_customer).to receive(:subscriptions)
>       expect(user.subscription_cancelled_at).to eq future_date
>     end
>
>     it 'returns false otherwise' do
>       allow(user).to receive(:stripe_customer).and_return(stripe_customer)
>       allow(stripe_customer).to
> receive(:subscriptions).and_return([subscription])
>       expect(user).to receive(:stripe_customer)
>       expect(stripe_customer).to receive(:subscriptions)
>       expect(user.subscription_cancelled_at).to be_nil
>     end
>   end
>
>
> All that’s really going on here is that I’m passing the dates through some
> data structures and eventually returning the expected dates. There is no
> date math (or conversion) involved behind the scenes. However, I get these
> results:
>
>   1) User::StripeCustomer#subscription_cancelled_at returns canceled_at if
> it is populated
>      Failure/Error: expect(user.subscription_cancelled_at.utc).to eq
> @@past_date
>
>
>        expected: 2021-02-11 18:48:06.455547000 +0000
>             got: 2021-02-11 18:48:06.455546855 +0000
>
>
>        (compared using ==)
>
>
>        Diff:
>        @@ -1 +1 @@
>        -Thu, 11 Feb 2021 18:48:06 UTC +00:00
>        +2021-02-11 18:48:06 UTC
>
>
>      # ./spec/models/user/stripe_customer_spec.rb:312:in `block (3
> levels) in <top (required)>'
>
>   2) User::StripeCustomer#subscription_cancelled_at returns
> current_period_end if subscription will cancel at period end
>      Failure/Error: expect(user.subscription_cancelled_at).to eq
> @@future_date
>
>
>        expected: 2021-03-11 18:48:06.455753000 +0000
>             got: 2021-03-11 10:48:06.455752849 -0800
>
>
>        (compared using ==)
>
>
>        Diff:
>        @@ -1 +1 @@
>        -Thu, 11 Mar 2021 18:48:06 UTC +00:00
>        +2021-03-11 10:48:06 -0800
>
>
>      # ./spec/models/user/stripe_customer_spec.rb:321:in `block (3
> levels) in <top (required)>'
>
>
> Notice that the times being compared are off by very small amounts (< 1
> sec). I tried replacing the “let!” commands with assignments to class
> variables (@@past_date, etc) in an attempt to ensure that the let! blocks
> were not being re-evaluated each time they were referenced, but that was
> not the case.
>
> I can certainly change the test to check for a time “close” to the
> expected time, but that is a hack. Can anyone explain why I’m getting these
> differences?
>
> --
> 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 rspec+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/rspec/E9584261-2BFC-49BB-AC53-21991545F39F%40pobox.com
> <https://groups.google.com/d/msgid/rspec/E9584261-2BFC-49BB-AC53-21991545F39F%40pobox.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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 rspec+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rspec/CAKRXwc2D%2B8kagXdvf_2_RS%2BrYnJg9Z1pCgaOR%2B-d_8xB37S4XQ%40mail.gmail.com.

Reply via email to