Skip to main content

DataStoreMock

This item only works when running on the server. Server

In-memory stand-in for a Roblox GlobalDataStore used by tests. It faithfully round-trips values through a deep copy (mimicking JSON serialization, so aliasing bugs surface the same way they would against a real datastore) and lets tests inject failures such as the 509 Personal-RCC block.

It is a first-class citizen of the datastore package: the DataStorePromises wrappers accept it anywhere a real datastore Instance is expected via DataStoreMock.isDataStoreMock.

local store = DataStoreMock.new("PlayerData", "SaveData")
store:SetRaw("key", { coins = 5 })

-- Simulate Roblox datastores being down
store:FailAllRequests(DataStoreMock.OPERATION_NOT_ALLOWED_509)

Properties

OPERATION_NOT_ALLOWED_509

DataStoreMock.OPERATION_NOT_ALLOWED_509: string

The error Roblox raises when datastore operations run on a Personal RCC. This is the real-world failure that motivated the mock.

Functions

isDataStoreMock

DataStoreMock.isDataStoreMock(valueany) → boolean

Returns whether the given value is a DataStoreMock. Used by DataStorePromises so the mock can stand in for a real datastore Instance.

new

DataStoreMock.new(
namestring?,
scopestring?
) → DataStoreMock

Constructs a new DataStoreMock.

SetYieldTime

DataStoreMock.SetYieldTime(
yieldTimenumber
) → ()

Sets how long (in seconds) each request yields before completing, to mimic real datastore latency. Defaults to 0 (no yield) so tests stay fast.

SetErrorInjector

DataStoreMock.SetErrorInjector(
errorInjector((ErrorInjectorContext) → string?)?
) → ()

Injects a callback consulted before every request. Returning a string from the callback makes that request throw the string as its error; returning nil lets the request proceed.

FailAllRequests

DataStoreMock.FailAllRequests(
errorMessagestring?--

Defaults to the 509 Personal-RCC error

) → ()

Makes every subsequent request throw the given error until DataStoreMock.StopFailing is called. Simulates a total datastore outage.

FailNextRequests

DataStoreMock.FailNextRequests(
countnumber,
errorMessagestring?--

Defaults to the 509 Personal-RCC error

) → ()

Makes the next count requests throw the given error, then recover. Simulates a transient outage that the retry logic is expected to survive.

StopFailing

DataStoreMock.StopFailing(selfDataStoreMock) → ()

Clears any injected failures.

BlockRequests

DataStoreMock.BlockRequests(selfDataStoreMock) → ()

Makes every subsequent request hang (yield) inside the datastore call until DataStoreMock.UnblockRequests is called. Simulates a request that does not settle -- e.g. a lock command that can take up to ~30s to propagate across servers -- so tests can exercise a request in flight (and its maid cancelling the yielding thread).

UnblockRequests

DataStoreMock.UnblockRequests(selfDataStoreMock) → ()

Releases requests blocked by DataStoreMock.BlockRequests. A request whose thread was cancelled while blocked never resumes.

GetCallCount

DataStoreMock.GetCallCount(
methodstring?--

e.g. "GetAsync", "UpdateAsync"

) → number

Returns the number of times a given API was called (or total across all APIs when no method is given). Failed calls count too.

SetRaw

DataStoreMock.SetRaw(
keystring,
valueany
) → ()

Directly seeds a stored value without datastore semantics (no version bump, no failure injection). For test setup.

GetRaw

DataStoreMock.GetRaw(
keystring
) → any

Directly reads a stored value without datastore semantics. For test assertions.

GetAsync

DataStoreMock.GetAsync(
keystring
) → (
any,
any
)--

value, keyInfo

Mimics GlobalDataStore:GetAsync.

SetAsync

DataStoreMock.SetAsync(
keystring,
valueany,
userIds{number}?,
optionsany?
) → string--

version

Mimics GlobalDataStore:SetAsync.

UpdateAsync

DataStoreMock.UpdateAsync(
keystring,
transformFunction(
any,
any
) → ...any
) → (
any,
any
)--

value, keyInfo

Mimics GlobalDataStore:UpdateAsync. The transform receives the current value and a key-info stand-in, and returns newValue [, userIds [, metadata]]. Returning nil cancels the update (matching Roblox semantics).

RemoveAsync

DataStoreMock.RemoveAsync(
keystring
) → (
any,
any
)--

removed value, keyInfo

Mimics GlobalDataStore:RemoveAsync.

IncrementAsync

DataStoreMock.IncrementAsync(
keystring,
deltanumber?
) → number

Mimics GlobalDataStore:IncrementAsync.

Show raw api
{
    "functions": [
        {
            "name": "isDataStoreMock",
            "desc": "Returns whether the given value is a [DataStoreMock]. Used by [DataStorePromises] so the\nmock can stand in for a real datastore `Instance`.",
            "params": [
                {
                    "name": "value",
                    "desc": "",
                    "lua_type": "any"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 82,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "new",
            "desc": "Constructs a new DataStoreMock.",
            "params": [
                {
                    "name": "name",
                    "desc": "",
                    "lua_type": "string?"
                },
                {
                    "name": "scope",
                    "desc": "",
                    "lua_type": "string?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "DataStoreMock"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 93,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "SetYieldTime",
            "desc": "Sets how long (in seconds) each request yields before completing, to mimic real\ndatastore latency. Defaults to 0 (no yield) so tests stay fast.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                },
                {
                    "name": "yieldTime",
                    "desc": "",
                    "lua_type": "number"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 119,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "SetErrorInjector",
            "desc": "Injects a callback consulted before every request. Returning a string from the callback\nmakes that request throw the string as its error; returning nil lets the request proceed.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                },
                {
                    "name": "errorInjector",
                    "desc": "",
                    "lua_type": "((ErrorInjectorContext) -> string?)?"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 131,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "FailAllRequests",
            "desc": "Makes every subsequent request throw the given error until [DataStoreMock.StopFailing]\nis called. Simulates a total datastore outage.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                },
                {
                    "name": "errorMessage",
                    "desc": "Defaults to the 509 Personal-RCC error",
                    "lua_type": "string?"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 143,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "FailNextRequests",
            "desc": "Makes the next `count` requests throw the given error, then recover. Simulates a\ntransient outage that the retry logic is expected to survive.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                },
                {
                    "name": "count",
                    "desc": "",
                    "lua_type": "number"
                },
                {
                    "name": "errorMessage",
                    "desc": "Defaults to the 509 Personal-RCC error",
                    "lua_type": "string?"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 159,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "StopFailing",
            "desc": "Clears any injected failures.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 177,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "BlockRequests",
            "desc": "Makes every subsequent request hang (yield) inside the datastore call until\n[DataStoreMock.UnblockRequests] is called. Simulates a request that does not settle -- e.g. a\nlock command that can take up to ~30s to propagate across servers -- so tests can exercise a\nrequest in flight (and its maid cancelling the yielding thread).",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 187,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "UnblockRequests",
            "desc": "Releases requests blocked by [DataStoreMock.BlockRequests]. A request whose thread was cancelled\nwhile blocked never resumes.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 195,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "GetCallCount",
            "desc": "Returns the number of times a given API was called (or total across all APIs when no\nmethod is given). Failed calls count too.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                },
                {
                    "name": "method",
                    "desc": "e.g. \"GetAsync\", \"UpdateAsync\"",
                    "lua_type": "string?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "number"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 206,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "SetRaw",
            "desc": "Directly seeds a stored value without datastore semantics (no version bump, no failure\ninjection). For test setup.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                },
                {
                    "name": "key",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "value",
                    "desc": "",
                    "lua_type": "any"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 220,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "GetRaw",
            "desc": "Directly reads a stored value without datastore semantics. For test assertions.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                },
                {
                    "name": "key",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "any"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 232,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "GetAsync",
            "desc": "Mimics `GlobalDataStore:GetAsync`.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                },
                {
                    "name": "key",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "value, keyInfo",
                    "lua_type": "(any, any)"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 288,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "SetAsync",
            "desc": "Mimics `GlobalDataStore:SetAsync`.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                },
                {
                    "name": "key",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "value",
                    "desc": "",
                    "lua_type": "any"
                },
                {
                    "name": "userIds",
                    "desc": "",
                    "lua_type": "{ number }?"
                },
                {
                    "name": "options",
                    "desc": "",
                    "lua_type": "any?"
                }
            ],
            "returns": [
                {
                    "desc": "version",
                    "lua_type": "string"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 305,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "UpdateAsync",
            "desc": "Mimics `GlobalDataStore:UpdateAsync`. The transform receives the current value and a\nkey-info stand-in, and returns `newValue [, userIds [, metadata]]`. Returning nil cancels\nthe update (matching Roblox semantics).",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                },
                {
                    "name": "key",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "transformFunction",
                    "desc": "",
                    "lua_type": "(any, any) -> ...any"
                }
            ],
            "returns": [
                {
                    "desc": "value, keyInfo",
                    "lua_type": "(any, any)"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 335,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "RemoveAsync",
            "desc": "Mimics `GlobalDataStore:RemoveAsync`.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                },
                {
                    "name": "key",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "removed value, keyInfo",
                    "lua_type": "(any, any)"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 368,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        },
        {
            "name": "IncrementAsync",
            "desc": "Mimics `GlobalDataStore:IncrementAsync`.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "DataStoreMock"
                },
                {
                    "name": "key",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "delta",
                    "desc": "",
                    "lua_type": "number?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "number"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 390,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        }
    ],
    "properties": [
        {
            "name": "OPERATION_NOT_ALLOWED_509",
            "desc": "The error Roblox raises when datastore operations run on a Personal RCC. This is the\nreal-world failure that motivated the mock.",
            "lua_type": "string",
            "source": {
                "line": 46,
                "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
            }
        }
    ],
    "types": [],
    "name": "DataStoreMock",
    "desc": "In-memory stand-in for a Roblox `GlobalDataStore` used by tests. It faithfully\nround-trips values through a deep copy (mimicking JSON serialization, so aliasing\nbugs surface the same way they would against a real datastore) and lets tests inject\nfailures such as the `509` Personal-RCC block.\n\nIt is a first-class citizen of the datastore package: the `DataStorePromises` wrappers\naccept it anywhere a real datastore `Instance` is expected via\n[DataStoreMock.isDataStoreMock].\n\n```lua\nlocal store = DataStoreMock.new(\"PlayerData\", \"SaveData\")\nstore:SetRaw(\"key\", { coins = 5 })\n\n-- Simulate Roblox datastores being down\nstore:FailAllRequests(DataStoreMock.OPERATION_NOT_ALLOWED_509)\n```",
    "realm": [
        "Server"
    ],
    "source": {
        "line": 23,
        "path": "src/datastore/src/Server/Mocks/DataStoreMock.lua"
    }
}