github.com/xmlking/toolkit/broker/pubsub@v0.3.4/message_mock_test.go (about)

     1  package broker
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"reflect"
     7  	"testing"
     8  	"time"
     9  	"unsafe"
    10  
    11  	"cloud.google.com/go/pubsub"
    12  )
    13  
    14  // AckHandler implements ack/nack handling.
    15  type AckHandler interface {
    16  	// OnAck processes a message ack.
    17  	OnAck()
    18  
    19  	// OnNack processes a message nack.
    20  	OnNack()
    21  }
    22  
    23  type makeAckHandler struct {
    24  	t *testing.T
    25  }
    26  
    27  func (ah *makeAckHandler) OnAck() {
    28  	ah.t.Logf("OnAck")
    29  }
    30  func (ah *makeAckHandler) OnNack() {
    31  	ah.t.Logf("OnNack")
    32  }
    33  
    34  func makeMockMessage(ackHandler AckHandler, t *testing.T) pubsub.Message {
    35  	t.Helper()
    36  	message := pubsub.Message{
    37  		ID:              "1",
    38  		Data:            []byte("ABC"),
    39  		Attributes:      map[string]string{"att1": "val1"},
    40  		PublishTime:     time.Now(),
    41  		DeliveryAttempt: nil,
    42  		OrderingKey:     "1",
    43  	}
    44  
    45  	//Get a reflectable value of message
    46  	messageValue := reflect.ValueOf(message)
    47  
    48  	// The value above is unaddressable. So construct a new and addressable message and set it with the value of the unaddressable
    49  	addressableValue := reflect.New(messageValue.Type()).Elem()
    50  	addressableValue.Set(messageValue)
    51  
    52  	//Get message's doneFunc field
    53  	//doneFuncField := addressableValue.FieldByName("doneFunc")
    54  	doneFuncField := addressableValue.FieldByName("ackh")
    55  
    56  	//Get the address of the field
    57  	doneFuncFieldAddress := doneFuncField.UnsafeAddr()
    58  
    59  	//Create a pointer based on the address
    60  	doneFuncFieldPointer := unsafe.Pointer(doneFuncFieldAddress)
    61  
    62  	//Create a new, exported field element that points to the original
    63  	accessibleDoneFuncField := reflect.NewAt(doneFuncField.Type(), doneFuncFieldPointer).Elem()
    64  
    65  	//Set the field with the alternative doneFunc
    66  	accessibleDoneFuncField.Set(reflect.ValueOf(ackHandler))
    67  
    68  	return addressableValue.Interface().(pubsub.Message)
    69  }
    70  
    71  func setup() {
    72  	fmt.Println("Setup...")
    73  }
    74  
    75  func teardown() {
    76  	fmt.Println("Teardown...")
    77  }
    78  
    79  func TestMain(m *testing.M) {
    80  	setup()
    81  	code := m.Run()
    82  	teardown()
    83  	os.Exit(code)
    84  }
    85  
    86  func TestPubsubMessage_Ack(t *testing.T) {
    87  	//Create an alternative AckHandler
    88  	ackHandler := &makeAckHandler{t}
    89  	message := makeMockMessage(ackHandler, t)
    90  
    91  	t.Log(message)
    92  	message.Ack()
    93  	t.Log(message)
    94  }
    95  
    96  func TestPubsubMessage_Nack(t *testing.T) {
    97  	//Create an alternative done function
    98  	ackHandler := &makeAckHandler{t}
    99  	message := makeMockMessage(ackHandler, t)
   100  
   101  	t.Log(message)
   102  	message.Nack()
   103  	t.Log(message)
   104  }