Tink is designed to be easily testable. This guide covers unit testing with Mox, integration testing with Bypass, and using Tink's sandbox environment.
Unit Testing with Mox
Tink defines Tink.HTTPBehaviour so you can mock the HTTP layer:
# test/support/mocks.ex
Mox.defmock(Tink.HTTPMock, for: Tink.HTTPBehaviour)# config/test.exs
config :tink,
http_adapter: Tink.HTTPMock,
enable_rate_limiting: false,
cache: [enabled: false]# test/my_feature_test.exs
defmodule MyFeatureTest do
use ExUnit.Case, async: true
import Mox
setup :verify_on_exit!
test "lists accounts" do
Tink.HTTPMock
|> expect(:get, fn _client, "/api/v1/accounts", _opts ->
{:ok, %{
"accounts" => [
%{"id" => "acc_1", "name" => "Current Account", "balance" => 1500}
]
}}
end)
{:ok, client} = Tink.Client.new(client_id: "test", client_secret: "test")
assert {:ok, [%{id: "acc_1"}]} = Tink.Accounts.list(client)
end
endIntegration Testing with Bypass
Use Bypass to run a local HTTP server that intercepts real Finch requests:
defmodule Tink.AccountsIntegrationTest do
use ExUnit.Case
setup do
bypass = Bypass.open()
client = Tink.Client.new!(
client_id: "test_id",
client_secret: "test_secret",
base_url: "http://localhost:#{bypass.port}"
)
{:ok, bypass: bypass, client: client}
end
test "lists accounts", %{bypass: bypass, client: client} do
Bypass.expect_once(bypass, "GET", "/api/v1/accounts", fn conn ->
Plug.Conn.resp(conn, 200, Jason.encode!(%{
"accounts" => [%{"id" => "acc_1", "name" => "Checking"}]
}))
end)
assert {:ok, [%{id: "acc_1"}]} = Tink.Accounts.list(client)
end
endSandbox Environment
Tink provides a sandbox for end-to-end testing without real banks:
# config/test.exs
config :tink,
base_url: "https://api.tink.com", # Sandbox uses the same base URL
client_id: System.get_env("TINK_SANDBOX_CLIENT_ID"),
client_secret: System.get_env("TINK_SANDBOX_CLIENT_SECRET")In the sandbox you can use Tink's test providers (e.g. se-test-open-banking-redirect)
to simulate bank connections without real credentials.
Test Helpers
Disable rate limiting and caching in tests to avoid flakiness:
# config/test.exs
config :tink,
enable_rate_limiting: false,
cache: [enabled: false],
debug_mode: falseProperty-Based Testing
Use stream_data to fuzz-test parameter handling:
defmodule Tink.ParamTest do
use ExUnit.Case
use ExUnitProperties
property "list_transactions/2 never raises on arbitrary date strings" do
check all date <- StreamData.string(:alphanumeric, max_length: 20) do
result = Tink.Transactions.list(client(), date_from: date)
assert match?({:ok, _} | {:error, %Tink.Error{}}, result)
end
end
end