2

I am testing a function to send a mock request to a server using gomega and I want to verify that 1. the request has started 2. the request has completed. For this I am returning two booleans. They should both evaluate to true in the example below but the values will be subject to change. I have tried this:

g := gomega.NewGomegaWithT(t)
...
g.Eventually(func() (bool, bool) {
...
    start = false
    end = true

    if (request.status == "started") {
        start = true
    }
    if (request.status == "complete") {
        end = true
    }
    return start, end
}).Should(Equal((true, true))

But it seems that gomega's Equal() does not handle multiple variables. Is there any way around this? Is it bad practice to evaluate two return values ?

user2969402
  • 1,221
  • 3
  • 16
  • 26
  • 1
    How can something be complete if it has never started? Checking for "complete" should suffice. – Peter Apr 14 '18 at 11:15
  • I believe `start` and `end` are sample names, we can have as many return values as r1, r2, r3... without any particular meaning – vitr Apr 14 '18 at 11:48

2 Answers2

1

In gomega's doc, It has been said that multiple return is ok to be used.

The function that you pass to Eventually can have more than one return value. In that case, Eventually passes the first return value to the matcher and asserts that all other return values are nil or zero-valued. This allows you to use Eventually with functions that return a value and an error – a common pattern in Go

In your code, can you change this line

.Should(Equal((true, true)) to .Should(Equal(true, true).

That should fix the problem.

Edit:

I overlooked that Equal only receives one interface parameter. My bad.

For future reference, for comparing multiple values in gomega's eventually,Array of struct (or any datatype) can be useful.

  • 1
    ..and asserts that all other return values are nil or zero-valued, so, then the test will never pass if the function returns true and true. – vitr Apr 14 '18 at 11:53
  • I see. I only focused on Eventually functions. I overlooked that `Equal` only receives one interface parameter. My bad. – Abdullah Al Maruf - Tuhin Apr 14 '18 at 12:14
0

You can use a wrapper function I wrote based on your pseudocode

g := gomega.NewGomegaWithT(t)
...
testedFunc := func() (bool, bool) {
...
    start = false
    end = true

    if (request.status == "started") {
        start = true
    }
    if (request.status == "complete") {
        end = true
    }
    return start, end
}

g.Eventually(func() map[string]bool{
    r1,r2 := testedFunc()
    return map[string]bool{"start": r1, "end": r2}
}).Should(Equal(map[string]bool{"start": true, "end": true}))

I'm using a map instead of simple r1&r2for verbosity, so, you can see what is actually wrong with the results. In my opinion, it's a bad practice to compare 2 return values unless the second one is an error. You can always combine multiple return values in a single language construct (map, slice, struct, etc.) as I did in my wrapper function. I understand it's hard to do with the async Eventually method, but in general, I'd try to assert each of the return values separately.

vitr
  • 6,766
  • 8
  • 30
  • 50