Receiving "unable to decode the activity function input payload with error" When Calling Activity With Mock Object

Hello,

I am attempting to test an activity called GetStatementsByFurnishmentIDActivity. Here is the signature:
func GetStatementsByFurnishmentIDActivity(ctx context.Context, input inputs.FurnishDataInput) (responses.GetStatementsByFurnishmentIDActivityResponse, error)

The activity’s input and response structs takes the following form:

type FurnishDataInput struct {
	FurnishmentID string
	client.FurnishmentAPI // this is an interface
}

type GetStatementsByFurnishmentIDActivityResponse struct {
	Statements     []models.Statement `json:"statements"`
	StatementCount int                `json:"statementCount"`
}

The FurnishmentAPI interface from the input above is defined as follows:

type FurnishmentAPI interface {
    Authenticate(ctx context.Context, username, password string) error
    GetStatementsByFurnishmentID(ctx context.Context, furnishmentID string) ([]models.Statement, error)
    GetFurnishmentHeader(ctx context.Context, furnishmentID string) (models.HeaderRecord, error)
    GetStatementBaseSegment(ctx context.Context, statementID, bureau string) (models.BaseSegment, error)
    Raw(ctx context.Context, data RequestData, out interface{}) error
}

In my test file, I am creating a mock struct that complies with the interface, and passing it to the activity as part of the input:

type mockFurnishmentAPI struct {
}

func newMockFurnishmentAPI() client.Furnishment {
        return &mockFurnishmentAPI{}
}

func (mfa *mockFurnishmentAPI) Authenticate(ctx context.Context, username, password string) error {
	return nil
}

func (mfa *mockFurnishmentAPI) GetStatementsByFurnishmentID(ctx context.Context, furnishmentID string) ([]models.Statement, error) {
	return []models.Statement{}, nil
}

func (mfa *mockFurnishmentAPI) GetFurnishmentHeader(ctx context.Context, furnishmentID string) (models.HeaderRecord, error) {
	return models.HeaderRecord{}, nil
}

func (mfa *mockFurnishmentAPI) GetStatementBaseSegment(ctx context.Context, statementID, bureau string) (models.BaseSegment, error) {
	return models.BaseSegment{}, nil
}

func (mfa *mockFurnishmentAPI) Raw(ctx context.Context, data client.RequestData, out interface{}) error {
	return nil
}
...
input := inputs.FurnishDataInput{
		FurnishmentID:  "testId",
		FurnishmentAPI: newMockFurnishmentAPI(),
	}

	res, err := s.env.ExecuteActivity(GetStatementsByFurnishmentIDActivity, input)
	if err != nil {
		fmt.Println(err)
	}
	actualResponse := responses.GetStatementsByFurnishmentIDActivityResponse{}
	err = res.Get(&actualResponse)

However, the execution of the activity is failing on the Get call with the following error:

unable to decode the activity function input payload with error: payload item 0: unable to decode: json: cannot unmarshal object into Go struct field FurnishDataInput.FurnishmentAPI of type client.FurnishmentAPI for function name: GetStatementsByFurnishmentIDActivity

I have also tried this without using a mock and using the actual struct from the library code, just to see if my mock was somehow incorrect, but received the same error.

I’m unsure where the json decoding is coming into play here. I assume Temporal is doing something under the hood, but I can’t see what’s wrong with what I’m doing/why I’m receiving this message. Do I need to use a custom DataConverter with this input struct? Any help would be appreciated.

Thanks,
Mike

Upon further testing, defining any interface field on the input object seems to be resulting in this error so far. Just tried it with a super simple test interface.

Have done some more digging & this actually looks to be expected behavior with Go. Go doesn’t know how to unmarshal interfaces without explicitly reverse-pairing them with a struct (which I don’t think I can do here as the unmarshalling is happening under the hood). Looks like I’ll just have to do some refactoring.

Thanks,
Mike