Skip to content

Mocking Context and ValkeyString so it can be unit tested#228

Draft
dmitrypol wants to merge 4 commits intovalkey-io:mainfrom
dmitrypol:mock-context2
Draft

Mocking Context and ValkeyString so it can be unit tested#228
dmitrypol wants to merge 4 commits intovalkey-io:mainfrom
dmitrypol:mock-context2

Conversation

@dmitrypol
Copy link
Copy Markdown
Collaborator

@dmitrypol dmitrypol commented Apr 16, 2026

Introduces a ContextTrait abstraction over Context and a mockall-generated MockContext so command handlers can be unit-tested without a live Valkey server.

New mock infrastructure (src/context/mock/):

  • ContextTrait + MockContext — logging, call, module options, server version, auth,
    and the full client API (get_client_id, get_client_name*, set_client_name*,
    get_client_username*, get_client_cert, get_client_info*, get_client_ip*,
    deauthenticate_and_close_client*, config_get).

  • CommandFilterCtxTrait + MockCommandFilterCtx — args_count, arg_get,
    arg_get_try_as_str, cmd_get_try_as_str, get_all_args_wo_cmd, arg_replace, arg_insert,
    arg_delete, feature-gated get_client_id.

  • InfoContextTrait + MockInfoContext — build_one_section.

  • Mock* — generated via #[mockall::automock], gated behind cfg(test) or the new test-mocks feature so release builds don't pull in mockall.

Introduced redismodule_test.rs with ValkeyString::create_for_test test harness for ValkeyString, implemented by mocking just enough of the Valkey string API to run unit tests entirely in Rust. Will NOT impact any real code

Cargo

  • mockall = "0.14" added as an optional dep + dev-dep.
  • New test-mocks feature enables downstream unit testing

Updated examples to use the new impl for real code and mocks / ValkeyString::create_for_test for unit tests

@dmitrypol dmitrypol marked this pull request as draft April 16, 2026 14:45
Copy link
Copy Markdown
Member

@stockholmux stockholmux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm far from being even Rust competent, but this looks okay. However, broadly, if you want people to use these features they need to be very explicitly documented and front and centre in your README.

Copy link
Copy Markdown
Contributor

@PDXKimani PDXKimani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Thinking about this, I think my main question is as to what putting the mock traits/derives within the crate itself is providing here. So far the only consumer I'm seeing are in the examples. I think it's fine to pattern-set how one can use a dependency injection approach to "mock" the module interface, but I think the approach on display currently doesn't actually require any internal access to the module crate? That is, if the mock definitions lived externally to the module crate, it wouldn't affect the examples' usage at all.

If we intend to use ContextTrait internally to the module crate to allow consumers to control dependency injection for the module itself, that's a bit of different story. If the module layer has sufficient complexity over the underlying C API that there'd be value in doing so, then I would see the argument for including that trait in the crate, though I still think I'd leave the decision of what mocking framework to use/how to implement a mocked version up to the consumer.

With regards to the mechanical usage of mocking in the examples, that seems fine.

@dmitrypol
Copy link
Copy Markdown
Collaborator Author

to clarify I want to use this Mock context in various modules that I am building. Currently I am unable to test functions that require passing &Context. This will allow me to throughly unit test that code.

updated examples to include tests

Signed-off-by: dmitrypol <dmitrypol@users.noreply.github.com>
@dmitrypol dmitrypol force-pushed the mock-context2 branch 5 times, most recently from 7847040 to 7eae477 Compare April 19, 2026 21:30
updated examples with unit tests

Signed-off-by: dmitrypol <dmitrypol@users.noreply.github.com>
@dmitrypol dmitrypol force-pushed the mock-context2 branch 3 times, most recently from f586930 to 5d6fff3 Compare April 20, 2026 21:23
@dmitrypol dmitrypol marked this pull request as ready for review April 20, 2026 21:24
@dmitrypol dmitrypol changed the title Mocking Context so it can be unit tested Mocking Context and ValkeyString so it can be unit tested Apr 20, 2026
@dmitrypol dmitrypol force-pushed the mock-context2 branch 4 times, most recently from a98b7f0 to 46f6fc2 Compare April 21, 2026 20:24
updated examples to use it

Signed-off-by: dmitrypol <dmitrypol@users.noreply.github.com>
@dmitrypol dmitrypol marked this pull request as draft April 22, 2026 20:14
Copy link
Copy Markdown
Member

@KarthikSubbarao KarthikSubbarao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @dmitrypol , The main comment I have would be to have each "Context" like struct mocked internally, without requiring a user to switch to a new trait. Each Context can have a startmock / shim invocation at the beginning of unit test runs where it points the Raw Module APIs to mocked APIs. By having this startmock / shim automatically executed from the unit test execution, users will not have to refactor their business logic, and will get the mock functionality to their benefit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants