@@ -474,3 +474,168 @@ func TestContextExecErrorDelay(t *testing.T) {
474474 t .Errorf ("expecting a delay of less than %v before error, actual delay was %v" , delay , elapsed )
475475 }
476476}
477+
478+ // TestMonitorPingsDisabled verifies backwards-compatibility with behaviour of the library in which
479+ // calls to Ping are not mocked out. It verifies this persists when the user does not enable the new
480+ // behaviour.
481+ func TestMonitorPingsDisabled (t * testing.T ) {
482+ t .Parallel ()
483+ db , mock , err := New ()
484+ if err != nil {
485+ t .Errorf ("an error '%s' was not expected when opening a stub database connection" , err )
486+ }
487+ defer db .Close ()
488+
489+ // When monitoring of pings is not enabled in the mock, calling Ping should have no effect.
490+ err = db .Ping ()
491+ if err != nil {
492+ t .Errorf ("monitoring of pings is not enabled so did not expect error from Ping, got '%s'" , err )
493+ }
494+
495+ // Calling ExpectPing should also not register any expectations in the mock. The return from
496+ // ExpectPing should be nil.
497+ expectation := mock .ExpectPing ()
498+ if expectation != nil {
499+ t .Errorf ("expected ExpectPing to return a nil pointer when monitoring of pings is not enabled" )
500+ }
501+
502+ err = mock .ExpectationsWereMet ()
503+ if err != nil {
504+ t .Errorf ("monitoring of pings is not enabled so ExpectPing should not register an expectation, got '%s'" , err )
505+ }
506+ }
507+
508+ func TestPingExpectations (t * testing.T ) {
509+ t .Parallel ()
510+ db , mock , err := New (MonitorPingsOption (true ))
511+ if err != nil {
512+ t .Errorf ("an error '%s' was not expected when opening a stub database connection" , err )
513+ }
514+ defer db .Close ()
515+
516+ mock .ExpectPing ()
517+ if err := db .Ping (); err != nil {
518+ t .Fatal (err )
519+ }
520+
521+ if err := mock .ExpectationsWereMet (); err != nil {
522+ t .Errorf ("there were unfulfilled expectations: %s" , err )
523+ }
524+ }
525+
526+ func TestPingExpectationsErrorDelay (t * testing.T ) {
527+ t .Parallel ()
528+ db , mock , err := New (MonitorPingsOption (true ))
529+ if err != nil {
530+ t .Errorf ("an error '%s' was not expected when opening a stub database connection" , err )
531+ }
532+ defer db .Close ()
533+
534+ var delay time.Duration
535+ delay = 100 * time .Millisecond
536+ mock .ExpectPing ().
537+ WillReturnError (errors .New ("slow fail" )).
538+ WillDelayFor (delay )
539+
540+ start := time .Now ()
541+ err = db .Ping ()
542+ stop := time .Now ()
543+
544+ if err == nil {
545+ t .Errorf ("result was not expected, was not expecting nil error" )
546+ }
547+
548+ if err .Error () != "slow fail" {
549+ t .Errorf ("error '%s' was not expected, was expecting '%s'" , err .Error (), "slow fail" )
550+ }
551+
552+ elapsed := stop .Sub (start )
553+ if elapsed < delay {
554+ t .Errorf ("expecting a delay of %v before error, actual delay was %v" , delay , elapsed )
555+ }
556+
557+ mock .ExpectPing ().WillReturnError (errors .New ("fast fail" ))
558+
559+ start = time .Now ()
560+ db .Ping ()
561+ stop = time .Now ()
562+
563+ elapsed = stop .Sub (start )
564+ if elapsed > delay {
565+ t .Errorf ("expecting a delay of less than %v before error, actual delay was %v" , delay , elapsed )
566+ }
567+ }
568+
569+ func TestPingExpectationsMissingPing (t * testing.T ) {
570+ t .Parallel ()
571+ db , mock , err := New (MonitorPingsOption (true ))
572+ if err != nil {
573+ t .Errorf ("an error '%s' was not expected when opening a stub database connection" , err )
574+ }
575+ defer db .Close ()
576+
577+ mock .ExpectPing ()
578+
579+ if err = mock .ExpectationsWereMet (); err == nil {
580+ t .Fatalf ("was expecting an error, but there wasn't one" )
581+ }
582+ }
583+
584+ func TestPingExpectationsUnexpectedPing (t * testing.T ) {
585+ t .Parallel ()
586+ db , _ , err := New (MonitorPingsOption (true ))
587+ if err != nil {
588+ t .Errorf ("an error '%s' was not expected when opening a stub database connection" , err )
589+ }
590+ defer db .Close ()
591+
592+ if err = db .Ping (); err == nil {
593+ t .Fatalf ("was expecting an error, but there wasn't any" )
594+ }
595+ }
596+
597+ func TestPingOrderedWrongOrder (t * testing.T ) {
598+ t .Parallel ()
599+ db , mock , err := New (MonitorPingsOption (true ))
600+ if err != nil {
601+ t .Errorf ("an error '%s' was not expected when opening a stub database connection" , err )
602+ }
603+ defer db .Close ()
604+
605+ mock .ExpectBegin ()
606+ mock .ExpectPing ()
607+ mock .MatchExpectationsInOrder (true )
608+
609+ if err = db .Ping (); err == nil {
610+ t .Fatalf ("was expecting an error, but there wasn't any" )
611+ }
612+ }
613+
614+ func TestPingExpectationsContextTimeout (t * testing.T ) {
615+ t .Parallel ()
616+ db , mock , err := New (MonitorPingsOption (true ))
617+ if err != nil {
618+ t .Errorf ("an error '%s' was not expected when opening a stub database connection" , err )
619+ }
620+ defer db .Close ()
621+
622+ mock .ExpectPing ().WillDelayFor (time .Hour )
623+
624+ ctx , cancel := context .WithTimeout (context .Background (), 50 * time .Millisecond )
625+ defer cancel ()
626+
627+ doneCh := make (chan struct {})
628+ go func () {
629+ err = db .PingContext (ctx )
630+ close (doneCh )
631+ }()
632+
633+ select {
634+ case <- doneCh :
635+ if err != ErrCancelled {
636+ t .Errorf ("expected error '%s' to be returned from Ping, but got '%s'" , ErrCancelled , err )
637+ }
638+ case <- time .After (time .Second ):
639+ t .Errorf ("expected Ping to return after context timeout, but it did not in a timely fashion" )
640+ }
641+ }
0 commit comments