Skip to content

expectto/be

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

54 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

be β€” a bee minus one letter

Expect(πŸ‘¨πŸΌβ€πŸ’»).To(Be(πŸš€))

License Go Reference

expectto/be is a Golang package that offers a substantial collection of Be matchers. Every Be matcher is compatible with both Ginkgo/Gomega and Gomock. Where possible, arguments of matchers can be either finite values or matchers (Be/Gomega/Gomock).
Employing expectto/be matchers enables you to create straightforward, readable, and maintainable unit or integration tests in Golang. Tasks such as testing HTTP requests, validating JSON responses, and more become remarkably comprehensive and straightforward.

Table of Contents

Installation

To use Be in your Golang project, simply import it:

import "github.com/expectto/be"

Example

Consider the following example demonstrating the usage of expectto/be's HTTP request matchers:

req, err := buildRequestForServiceFoo()
Expect(err).To(Succeed())

// Matching an HTTP request
Expect(req).To(be_http.Request(
    // Matching the URL
    be_http.HavingURL(be_url.URL(
        be_url.WithHttps(),
        be_url.HavingHost("example.com"),
        be_url.HavingPath("/path"),
        be_url.HavingSearchParam("status", "active"),
        be_url.HavingSearchParam("v", be_reflected.AsNumericString()),
        be_url.HavingSearchParam("q", "Hello World"),
    )),

    // Matching the HTTP method
    be_http.POST(),

    // Matching the request's context
    be_http.HavingCtx(
        be_ctx.CtxWithDeadline(be_time.LaterThan(time.Now().Add(30*time.Minute))),
        be_ctx.CtxWithValue("foobar", 100),
    ),

    // Matching the request body using JSON matchers
    be_http.HavingBody(
        be.JSON(
            be_json.JsonAsReader,
            be_json.HaveKeyValue("hello", "world"),
            // NOTE: JSON numbers decode to float64, so use AsFloat (not AsInteger) here
            be_json.HaveKeyValue("n", be_reflected.AsFloat(), be_math.GreaterThan(10)),
            be_json.HaveKeyValue("ids", be_reflected.AsSliceOf[string]()),
            Not(be_json.HaveKeyValue("deleted_field")), // not to have a deleted field
            
            be_json.HaveKeyValue("email", be_string.ValidEmail(), HaveSuffix("@tests.com")),

            // "details":[{"key":"foo"},{"key":"bar"}]
            be_json.HaveKeyValue("details", And(
                be_reflected.AsObjects(),
                be.HaveLength(be_math.GreaterThan(2)),
                ContainElements(
                    be_json.HaveKeyValue("key", "foo"),
                    be_json.HaveKeyValue("key", "bar"),
                ),
            )),
        ),
    ),

	// Matching HTTP headers 
    be_http.HavingHeader("X-Custom", "Hey-There"), 
    be_http.HavingHeader("Authorization", 
        be_string.MatchTemplate("Bearer {{jwt}}", 
        be_string.V("jwt", 
            be_jwt.Token(
                be_jwt.Valid(), 
                be_jwt.HavingClaim("name", "John Doe"), 
            ), 
        ), 
    ),
))      

Test framework integration

be matchers are framework-agnostic. The core github.com/expectto/be module imports no test framework β€” pick how you run assertions:

Standard library (no extra deps). Two equivalent spellings β€” a fluent one and a flat, testify-style one β€” both backed by the same engine, both driven by the stdlib *testing.T:

import "github.com/expectto/be"

// fluent (ginkgo/gomega-flavored)
be.Expect(t, n).To(be_math.GreaterThan(10))    // soft fail (assert-style)
be.Require(t, n).To(be_math.GreaterThan(10))   // hard fail (require-style)
be.Expect(t, s).NotTo(be_string.EmptyString())

// flat (testify-flavored)
be.AssertThat(t, n, be_math.GreaterThan(10))     // soft fail (assert-style)
be.RequireThat(t, s, be_string.NonEmptyString()) // hard fail (require-style)

Already on testify? Keep your assert/require calls and reach for be only where a matcher earns its keep β€” be.AssertThat / be.RequireThat are the drop-in slots (no extra dependency):

assert.Equal(t, want, got)          // testify, as usual
be.AssertThat(t, got, be.Eq(want))  // be β€” and now `got` can face any matcher,
                                    // e.g. be_url.URL(be_url.HavingHost("x"), ...)

The subject comes first and the expected value lives inside the matcher (be.Eq(want)), so β€” unlike testify's Equal(t, want, got) β€” there's no want/got order to memorize or get wrong.

Ginkgo / Gomega: every be matcher already satisfies gomega's matcher interface, so use it directly inside Expect(...).To(...).

Mocking

be matchers also work as mock argument matchers:

Gomock: every be matcher already satisfies gomock.Matcher, so pass it directly:

mockObj.EXPECT().Do(be_math.GreaterThan(10)).Return("ok")

Testify mock / mockery: wrap with MatchedBy (works for hand-written and mockery-generated mocks) β€” the matcher equivalent of testify's own mock.MatchedBy. This is the one place you need the separate x/mock module (it's what keeps testify out of the core deps); install it with @latest (the submodule shares version numbers with the core module, which confuses go get <pkg>@<version>):

go get github.com/expectto/be/x/mock@latest
import bemock "github.com/expectto/be/x/mock"

svc.On("Do", bemock.MatchedBy(be_math.GreaterThan(10))).Return("ok")

Matchers

Core Be

πŸ“¦ be provides a set of core matchers for common testing scenarios.
See detailed docs

Core matchers:

Always, Never, All, Any, Eq, Not, HaveLength, Dive, DiveAny, DiveFirst

Everyday matchers:

Nil, NotNil, True, False, Eq, Ne, Empty, NotEmpty, Identical, NotIdentical, Via, Succeed, HaveOccurred, MatchError, Panic, NotPanic, ContainElement, ContainElements, ContainSubstring, HaveKey, HaveKeyWithValue

be_reflected

πŸ“¦ be_reflected provides Be matchers that use reflection, enabling expressive assertions on values' reflect kinds and types.
See detailed docs

General Matchers based on reflect.Kind:

AsKind, AsFunc, AsChan, AsPointer, AsFinalPointer, AsStruct, AsPointerToStruct, AsSlice, AsPointerToSlice, AsSliceOf, AsMap, AsPointerToMap, AsObject, AsObjects, AsPointerToObject

Data Type Matchers based on reflect.Kind

AsString, AsBytes, AsNumeric, AsNumericString, AsInteger, AsIntegerString, AsFloat, AsFloatishString,

Interface Matchers based on reflect.Kind

AsReader,AsStringer

Matchers based on types compatibility:

AssignableTo, Implementing

be_math

πŸ“¦ be_math provides Be matchers for mathematical operations.
See detailed docs

Matchers on math:

GreaterThan, GreaterThanEqual, LessThan, LessThanEqual, Approx, InRange, Odd, Even, Negative, Positive, Zero, Integral, DivisibleBy

Shortcut aliases for math matchers:

Gt, Gte, Lt, Lte

be_string

πŸ“¦ be_string provides Be matchers for string-related assertions.
See detailed docs

Matchers on strings

NonEmptyString, EmptyString, Alpha, Numeric, AlphaNumeric, AlphaNumericWithDots, Float, Titled, LowerCaseOnly, MatchWildcard, ValidEmail

Template matchers

MatchTemplate

be_time

πŸ“¦ be_time provides Be matchers on time.Time.
See detailed docs

Time Matchers

LaterThan, LaterThanEqual, EarlierThan, EarlierThanEqual, Eq, Approx,
SameExactMilli, SameExactSecond, SameExactMinute, SameExactHour,
SameExactDay, SameExactWeekday, SameExactWeek, SameExactMonth,
SameSecond, SameMinute, SameHour, SameDay, SameYearDay,
SameWeek, SameMonth, SameYear, SameTimzone, SameOffset, IsDST

be_jwt

πŸ“¦ be_jwt provides Be matchers for handling JSON Web Tokens (JWT). It includes matchers for transforming and validating JWT tokens. Matchers corresponds to specific golang jwt implementation.
See detailed docs

Transformers for JWT matching:

TransformSignedJwtFromString, TransformJwtFromString

Matchers on JWT:

Token, Valid, HavingClaims, HavingClaim, HavingMethodAlg, SignedVia

be_url

πŸ“¦ be_url provides Be matchers on url.URL.
See detailed docs

Transformers for URL Matchers:

TransformUrlFromString, TransformSchemelessUrlFromString

URL Matchers:

URL, Values, HavingHost, HavingHostname, HavingScheme, NotHavingScheme, WithHttps, WithHttp, HavingPort, NotHavingPort, HavingPath, HavingRawQuery, HavingSearchParam, NotHavingSearchParam, HavingMultipleSearchParam, HavingUsername, HavingUserinfo, HavingPassword

be_ctx

πŸ“¦ be_ctx provides Be matchers on context.Context.
See detailed docs

Context Matchers:

Ctx, CtxWithValue, CtxWithDeadline, CtxWithError

be_json

πŸ“¦ be_json provides Be matchers for expressive assertions on JSON.
See detailed docs

JSON Matchers:

Matcher, HaveKeyValue

be_http

πŸ“¦ be_http provides Be matchers for expressive assertions on http.Request.
See detailed docs

Matchers on HTTP:

Request, HavingMethod,
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, CONNECT, TRACE,
HavingURL, HavingBody, HavingHost, HavingProto, HavingCtx, HavingHeader, HavingHeaders

Contributing

Be welcomes contributions! Feel free to open issues, suggest improvements, or submit pull requests. Contribution guidelines for this project

License

This project is licensed under the MIT License.

About

Wide collection of Golang assertions: Gomega and Gomock compatible matchers

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Contributors