Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* [Code of Ethics](prestd/code-of-ethics.md)
* [Get pREST](get-prest/README.md)
* [Development Guide](get-prest/development-guide.md)
* [Mock Adapter](get-prest/mock-adapter.md)
* [Start with Docker](<README (1).md>)
* [Start with Golang](get-prest/start-with-golang.md)
* [Start with Homebrew](get-prest/start-with-homebrew.md)
Expand Down
2 changes: 2 additions & 0 deletions get-prest/development-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ That's it, you have a way to validate the project running locally, and to test o

pREST's unit tests depend on a working Postgres database for SQL query execution, to simplify the preparation of the local environment we use docker (and docker-compose) to upload the environment with Postgres.

For tests that do not need a real PostgreSQL connection, use the [mock adapter](mock-adapter.md) to queue scanner responses and exercise adapter-backed code paths in memory.

**all tests:**

```sh
Expand Down
86 changes: 86 additions & 0 deletions get-prest/mock-adapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Mock Adapter

The `github.com/prest/prest/v2/adapters/mock` package provides a lightweight
implementation of the `adapters.Adapter` interface for tests. It avoids a real
PostgreSQL connection and returns queued scanner responses from memory.

Use it when a controller, middleware, router, or other adapter-backed test needs
pREST behavior but does not need database-specific behavior.

## Basic usage

Create the adapter with the current test, then assign it to the global pREST
configuration used by the code under test:

```go
import (
"testing"

"github.com/prest/prest/v2/adapters/mock"
"github.com/prest/prest/v2/config"
)

func TestHandler(t *testing.T) {
adapter := mock.New(t)
config.PrestConf.Adapter = adapter

adapter.AddItem([]byte(`[{"id":1,"name":"prest"}]`), nil, false)

// Run code that calls config.PrestConf.Adapter.Query(...)
}
```

`mock.New(t)` also registers a `database/sql` driver named `mock`. The
transaction helpers use a mock DSN named `prest`, so tests can exercise
transaction paths without opening a network connection.

### Queued responses

The mock adapter stores responses in `Mock.Items`. Each query-like or
mutation-like method consumes the next queued item and returns it as a
`scanner.PrestScanner`.

Queue items with `AddItem`:

```go
adapter.AddItem(responseBody, responseError, isCount)
```

The arguments map to `mock.Item` fields:

* `responseBody`: JSON bytes returned by the scanner.
* `responseError`: error exposed by the scanner.
* `isCount`: count metadata returned by clause helpers such as `DatabaseClause`
and `SchemaClause`.

Add one item for each adapter operation the test expects. If code calls a
mocked operation that consumes a response and no items are queued, the mock
fails the test with `do not have any operations to perform`.

### Permissions

`TablePermissions` reads `config.PrestConf.AccessConf`. When access
restrictions are disabled, it returns `true`. When restrictions are enabled, it
checks table-level permissions first and then user-specific table permissions
when a user name is provided.

This lets tests cover authorization behavior without a database fixture:

```go
config.PrestConf.AccessConf.Restrict = true
config.PrestConf.AccessConf.Tables = []config.TablesConf{
{Name: "books", Permissions: []string{"read"}},
}

if !adapter.TablePermissions("books", "read", "") {
t.Fatal("expected read access")
}
```

### Generated mocks

This package is different from `adapters/mockgen`. The `mockgen` package is
generated by GoMock from the adapter interfaces and is useful when a test needs
strict call expectations. The `mock` package is hand-written and is better for
controller-style tests that need scanner responses and simple permission
behavior.