Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WithReply values getting interchanged during tests #7

Open
jaylane opened this issue Oct 9, 2018 · 8 comments
Open

WithReply values getting interchanged during tests #7

jaylane opened this issue Oct 9, 2018 · 8 comments

Comments

@jaylane
Copy link

jaylane commented Oct 9, 2018

My tests are passing half of the time and failing half of the time when using go-mocket mock and a response struct.

example test:

Describe("GetApplicationStatuses", func() {
		Context("on success", func() {
			It("should should write inReview and ineligible counts to context", func() {
				params := []gin.Param{gin.Param{Key: "company_id", Value: "1"}}

				mockContext.Params = params
				mockContext.Set("employeeIDs", []string{"1a"})

				mockReply := []map[string]interface{}{{"InReview": 1, "Ineligible": 2}}
				globalMock.NewMock().
					WithQuery("case when app.status in('SUBMITTED','REQUIRES_ACTION')").
					WithReply(mockReply)

				returnedFunc := GetApplicationStatuses()
				returnedFunc(mockContext)

				var expectValue = ApplicationStatus{InReview: 1, Ineligible: 2}
				Expect(mockContext.Value("Applications")).To(Equal(expectValue))
			})
		})

failure:

Expected
      <middleware.ApplicationStatus>: {InReview: 2, Ineligible: 1}
  to equal
      <middleware.ApplicationStatus>: {InReview: 1, Ineligible: 2}

func & struct being tested:

func GetApplicationStatuses() gin.HandlerFunc {
	return func(c *gin.Context) {
		var (
			inReview,
			ineligible int
			applications ApplicationStatus
		)

		rows, err := db.Table("application as app").
			Select("COALESCE(sum(case when app.status in('SUBMITTED','REQUIRES_ACTION') then 1 else 0 end),0) as in_review, "+
				"COALESCE(sum(case when app.status = 'INELIGIBLE' then 1 else 0 end),0) as ineligible").
			Where("app.id in(select employee.id from employee where employee.x_id in(?))", c.Value("employeeIDs")).
			Rows()

		if err != nil {
			utils.LogError(
				fmt.Sprintf("Error getting application statuses: %v", err),
				"middleware.GetApplicationStatuses",
			)

			c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
				"message": "Error getting application statuses.",
			})

			return
		}

		for rows.Next() {
			err := rows.Scan(&inReview, &ineligible)

			if err != nil {
				utils.LogError(
					fmt.Sprintf("Error getting application statuses: %v", err),
					"middleware.GetApplicationStatuses",
				)

				c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
					"message": "Error getting application statuses.",
				})

				return
			}

			applications = ApplicationStatus{inReview, ineligible}
		}

		c.Set("Applications", applications)
	}
}

// ApplicationStatus struct for response to GetApplicationStatuses
type ApplicationStatus struct {
	InReview   int `json:"inReview gorm:"column:InReview"`
	Ineligible int `json:"ineligible" gorm:"column:Ineligible"`
}

half of the time the test passes fine, the other half it fails because InReview and Ineligible values are swapped. I've been banging my head against the wall with it for a week now. any help would be greatly appreciated. Seems to be happening anytime I'm using a response struct or there is > 1 column on the WithReply. Thanks for a great mocking package btw.

@jaylane
Copy link
Author

jaylane commented Oct 21, 2018

still haven't been able to figure this out, added debugging logs to the test and func, on some occasion rows.Columns() swaps the order of how they should be returned by the query & reply adding test logs with debugs below:

`•••••2018/10/21 14:05:26 Mock Reply: [map[in_review:1 ineligible:2]]
2018/10/21 14:05:26 mock_catcher: check query: SELECT COALESCE(sum(case when app.status in('SUBMITTED','REQUIRES_ACTION') then 1 else 0 end),0) as in_review, COALESCE(sum(case when app.status = 'INELIGIBLE' then 1 else 0 end),0) as ineligible FROM application as app WHERE (app.id in(select employee.id from employee where employee.cs_id in(1a)))

[2018-10-21 14:05:26] [0.05ms] SELECT COALESCE(sum(case when app.status in('SUBMITTED','REQUIRES_ACTION') then 1 else 0 end),0) as in_review, COALESCE(sum(case when app.status = 'INELIGIBLE' then 1 else 0 end),0) as ineligible FROM application as app WHERE (app.id in(select employee.id from employee where employee.cs_id in('1a')))
[0 rows affected or returned ]
2018/10/21 14:05:26 Columns Returned: [ineligible in_review]


• Failure [0.001 seconds]
Contrib Middleware GetApplicationStatuses on success [It] should should write inReview and ineligible counts to context

Expected
<middleware.ApplicationStatus>: {InReview: 2, Ineligible: 1}
to equal
<middleware.ApplicationStatus>: {InReview: 1, Ineligible: 2}

@Selvatico
Copy link
Owner

Hi @jaylane, let me take look into. I will get back to you as soon as possible.

@hxmhlt
Copy link

hxmhlt commented Nov 7, 2018

@Selvatico I also encountered this problem.

@saurori
Copy link

saurori commented Apr 30, 2019

I am having the same issue. I am trying to mock replies for two SELECT queries, one count(*) and the other selecting columns (using sql QueryContext and rows.Next() / rows.Scan()). Half of the time the responses get swapped and the test fails.

@KaelBaldwin
Copy link

I am also having the same issue.

@saurori
Copy link

saurori commented May 23, 2019

I have since switched to: https://github.com/DATA-DOG/go-sqlmock . Appreciate the work put into go-mocket but the Datadog library has much better support.

@jaylane
Copy link
Author

jaylane commented Aug 7, 2019

any movement on this? @saurori does the datadog package support gorm?

@buildscientist
Copy link

@jaylane I'm wondering if go-mocket is looking at how the fields are returned by the DB driver.

In your SELECT statement - you're aliasing the InReview field as in_review and the Ineligible field as ineligible

Can you try modifying your mock reply as such:
mockReply := []map[string]interface{}{{"in_review": 1, "ineligible": 2}}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants