How do I create a mock function in Rust? [duplicate] - unit-testing

This question already has answers here:
How to mock external dependencies in tests? [duplicate]
(1 answer)
How to mock specific methods but not all of them in Rust?
(2 answers)
How can I test stdin and stdout?
(1 answer)
Is there a way of detecting whether code is being called from tests in Rust?
(1 answer)
What is the proper way to use the `cfg!` macro to choose between multiple implementations?
(1 answer)
Closed 2 years ago.
I'm trying to run unit tests on a function reducer . reducer takes in a struct State and an enum Action and returns a new struct State . When the action is Action::Status , I want the function state.status_function to be called on state. I'm having trouble testing that a mock function I pass into test_status is called with state. Does anyone know what I'm getting wrong in the code below?
fn test_status() {
let mut status_mock_called: bool;
let state = State {
status_function: Box::new(|state: State| {
status_mock_called = true;
return state;
}),
};
assert_eq!(root_reducer(state, Action::Status), state);
assert!(status_mock_called);
}
Outputs the error:
`(dyn std::ops::Fn(State) -> State + 'static)` doesn't implement `std::fmt::Debug`
How can I modify a rust variable from inside a function?
Here is the state struct in case it's relevant:
#[derive(Debug, Eq, PartialEq)]
struct State {
status_function: Box<dyn Fn(State) -> State>,
}
And here is the reducer:
fn root_reducer(state: State, action: Action) -> State {
match action {
Action::Status => (state.status_function)(state),
}
}

Related

Mocking just one function in Go [duplicate]

This question already has answers here:
Is it possible to mock a function imported from a package?
(5 answers)
Closed last year.
I've read a bunch about this and don't understand why mocking is so complicated in Go. Is there a simple way to mock just one function?
For example:
func addB(num int) int {
return b() + num;
}
func getB() int {
return 3;
}
If I want to test addB but change getB to respond with 6 or something instead, in other languages I'd write a unit test like:
expect(getB).toBeCalled.andRespond(5);
assertEqual(addB(2), 7);
I don't see a way to do the mocking in Go without creating an object with getB as one of its methods, creating an interface for that object, and then including a test interface sent with addB. Is that really the best way to do it?
You can declare a function as a variable and inject a mock implementation for the tests.
Example:
package main
import "fmt"
var getB = func() int {
return 3
}
func main() {
fmt.Println(getB())
getB = func() int {
return 5
}
fmt.Println(getB())
}

How to run setup code before any tests run in Rust?

I have a Rust app (a simple interpreter) that needs some setup (initialize a repo) before the environment is usable.
I understand that Rust runs its tests (via cargo test) in a multithreaded manner, so I need to initialize the repo before any tests run. I also need to do this only once per run, not before each test.
In Java's JUnit this would be done with a #BeforeClass (or #BeforeAll in JUnit 5) method. How can I acheive the same thing in Rust?
There's nothing built-in that would do this but this should help (you will need to call initialize() in the beginning of every test):
use std::sync::Once;
static INIT: Once = Once::new();
pub fn initialize() {
INIT.call_once(|| {
// initialization code here
});
}
If you use the ctor crate, you can take advantage of a global constructor function that will run before any of your tests are run.
Here's an example initialising the popular env_logger crate (assuming you have added ctor to your [dev-dependencies] section in your Cargo.toml file):
#[cfg(test)]
#[ctor::ctor]
fn init() {
env_logger::init();
}
The function name is unimportant and you may name it anything.
Just to give people more ideas (for example, how not to call setup in every test), one additional thing you could do is to write a helper like this:
fn run_test<T>(test: T) -> ()
where T: FnOnce() -> () + panic::UnwindSafe
{
setup();
let result = panic::catch_unwind(|| {
test()
});
teardown();
assert!(result.is_ok())
}
Then, in your own tests you would use it like this:
#[test]
fn test() {
run_test(|| {
let ret_value = function_under_test();
assert!(ret_value);
})
}
You can read more about UnwindSafe trait and catch_unwind here: https://doc.rust-lang.org/std/panic/fn.catch_unwind.html
I've found the original idea of this test helper in this medium article by Eric Opines.
Also, there is rstest crate which has pytest-like fixtures which you can use as a setup code (combined with the Jussi Kukkonen's answer:
use std::sync::Once;
use rstest::rstest;
static INIT: Once = Once::new();
pub fn setup() -> () {
INIT.call_once(|| {
// initialization code here
});
}
#[rstest]
fn should_success(setup: ()) {
// do your test
}
Maybe one day rstest will gain scopes support and Once won't be needed anymore.

swift3 - Singleton [duplicate]

This question already has answers here:
Using a dispatch_once singleton model in Swift
(30 answers)
Closed 6 years ago.
How can I convert this to Swift 3:
struct Static {
static var instance : myForm?
static var token : dispatch_once_t = 0
}
dispatch_once(&Static.token) {
Static.instance = myForm()
}
return Static.instance!
Just this:
static let instance = MyForm()
and call it
let form = MyForm.instance
A note from the documentation:
Stored type properties are lazily initialized on their first access. They are guaranteed to be initialized only once, even when accessed by multiple threads simultaneously, and they do not need to be marked with the lazy modifier.
PS: Consider that struct and class names are supposed to start with a capital letter.

Kotlin Anonymous Function Parameter Unit Testing

As per Kotlin Unit Testing for Function Parameter and Object, we could test the function variable funcParam, as it is an object function variable.
However if code is written using anonymous/inlining function parameter (which is a very nice Kotlin feature, that allow us to eliminate unnecessary temp variable for it)...
class MyClass1(val myObject: MyObject, val myObject2: MyObject2) {
fun myFunctionOne() {
myObject.functionWithFuncParam{
num: Int ->
// Do something to be tested
myObject2.println(num)
}
}
}
class MyObject () {
fun functionWithFuncParam(funcParam: (Int) -> Unit) {
funcParam(32)
}
}
How to write my unit test that test this part of code?
num: Int ->
// Do something to be tested
myObject2.println(num)
Or the inlining of the function parameter (as above) is something not good for unit testing, and hence should be avoided?
After a while discover the way to test it is to use Argument Captor.
#Test
fun myTest() {
val myClass1 = MyClass1(mockMyObject, mockMyObject2)
val argCaptor = argumentCaptor<(Int) -> Unit>()
val num = 1 //Any number to test
myClass1.myFunctionOne()
verify(mockMyObject).functionWithFuncParam(argCaptor.capture())
argCaptor.value.invoke(num)
// after that you could verify the content in the anonymous function call
verify(mockMyObject2).println(num)
}
For more info, refer to https://medium.com/#elye.project/how-to-unit-test-kotlins-private-function-variable-893d8a16b73f#.1f3v5mkql

Dart - Unit test for exception in constructor [duplicate]

This question already has answers here:
How do you unittest exceptions in Dart?
(7 answers)
Closed 7 years ago.
I write some simple project in Dart (1.9.3) with unit tests using unittest library. I have a problem with checking if constructor throws an error. Here's the sample code I write for this issue purposes:
class MyAwesomeClass {
String theKey;
MyAwesomeClass();
MyAwesomeClass.fromMap(Map someMap) {
if (!someMap.containsKey('the_key')) {
throw new Exception('Invalid object format');
}
theKey = someMap['the key'];
}
}
and here are the unit tests:
test('when the object is in wrong format', () {
Map objectMap = {};
expect(new MyAwesomeClass.fromMap(objectMap), throws);
});
The problem is the test fails with following message:
Test failed: Caught Exception: Invalid object format
What do I do wrong? Is it a bug in unittest or should I test exceptions with try..catch and check if exception has been thrown?
Thanks for all!
You can test if the Exception has been thrown using:
test('when the object is in wrong format', () {
Map objectMap = {};
expect(() => new MyAwesomeClass.fromMap(objectMap), throws);
});
passing as first argument an anonymous function raising the exception.