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 }