Examples: query, "exact match", wildcard*, wild?ard, wild*rd
Fuzzy search: cake~ (finds cakes, bake)
Term boost: "red velvet"^4, chocolate^2
Field grouping: tags:(+work -"fun-stuff")
Escape special characters +-&|!(){}[]^"~*?:\ - e.g. \+ \* \!
Range search: properties.timestamp:[1587729413488 TO *] (inclusive), properties.title:{A TO Z}(excluding A and Z)
Combinations: chocolate AND vanilla, chocolate OR vanilla, (chocolate OR vanilla) NOT "vanilla pudding"
Field search: properties.title:"The Title" AND text
 
← Back to post

Revisions 3

2 years ago
Hi Ethan, You have the right idea with mocking the decorator. In order for it to work, you could use monkeypatch to override the decorator with its mock and use importlib.reload to ensure that the changes are reflected (module caching appears to be the reason for which your mock isn't applying as expected. E.g You have a function that substracts 2 from a provided value, and a decorator defined in `mydecorator.py` that adds 4 to the value: ```python from mydecorator import add_four_decorator @add_four_decorator def subtract(a): return a - 2 ``` Mocking `add_four_decorator` in the unit test would look like the following: ```python import calculator def do_nothing(func): def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper def test_calculator_subtract(monkeypatch): monkeypatch.setattr('mydecorator.add_four_decorator', do_nothing) import importlib importlib.reload(calculator) res = calculator.subtract(12) assert res == 10 ``` Above we are grabbing the monkeypatch fixture and using `monkeypatch.setattr` to pass in the <file_path>.<function_name> of the decorator, and the decorator to replace it with as the second parameter. We are then using importlib.relead to import the module again (rather than using the cached file) to ensure the mock is applied. The same idea would apply with ajax here and your test_func_to_be_tested would contain something like this: ```python from q2_sdk.core import web async def test_func_to_be_tested(mock_success_class): ... monkeypatch.setattr('q2_sdk.core.web.ajax', mock_decorator) import importlib importlib.reload(web) actual = await handler.func_to_be_tested() assert isinstance(actual, type(mock_success)) ```
Hi Ethan, You have the right idea with mocking the decorator. In order for it to work, you could use monkeypatch to override the decorator with its mock and use importlib.reload to ensure that the changes are reflected (module caching appears to be the reason for which your mock isn't applying as expected. E.g You have a function that substracts 2 from a provided value, and a decorator defined in `mydecorator.py` that adds 4 to the value: ```python from mydecorator import add_four_decorator @add_four_decorator def subtract(a): return a - 2 ``` Mocking `add_four_decorator` in the unit test would look like the following: ```python from calculator def do_nothing(func): def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper def test_calculator_subtract(monkeypatch): monkeypatch.setattr('mydecorator.add_four_decorator', do_nothing) import importlib importlib.reload(calculator) res = calculator.subtract(12) assert res == 10 ``` Above we are grabbing the monkeypatch fixture and using `monkeypatch.setattr` to pass in the <file_path>.<function_name> of the decorator, and the decorator to replace it with as the second parameter. We are then using importlib.relead to import the module again (rather than using the cached file) to ensure the mock is applied. The same idea would apply with ajax here and your test_func_to_be_tested would contain something like this: ```python from q2_sdk.core import web async def test_func_to_be_tested(mock_success_class): ... monkeypatch.setattr('q2_sdk.core.web.ajax', mock_decorator) import importlib importlib.reload(web) actual = await handler.func_to_be_tested() assert isinstance(actual, type(mock_success)) ```
2 years ago
Hi Ethan, You have the right idea with mocking the decorator. In order for it to work, you could use monkeypatch to override the decorator with its mock and use importlib.reload to ensure that the changes are reflected (module caching appears to be the reason for which your mock isn't applying as expected. E.g You have a function that substracts 2 from a provided value, and a decorator defined in `mydecorator.py` that adds 4 to the value: ```python from mydecorator import add_four_decorator @add_four_decorator def subtract(a): return a - 2 ``` Mocking `add_four_decorator` in the unit test would look like the following: ```python from calculator def do_nothing(func): def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper def test_calculator_subtract(monkeypatch): monkeypatch.setattr('mydecorator.add_four_decorator', do_nothing) import importlib importlib.reload(calculator) res = calculator.subtract(12) assert res == 10 ``` Above we are grabbing the monkeypatch fixture and using `monkeypatch.setattr` to pass in the <file_path>.<function_name> of the decorator, and the decorator to replace it with as the second parameter. We are then using importlib.relead to import the module again (rather than using the cached file) to ensure the mock is applied. The same idea would apply with ajax here and your test_func_to_be_tested would contain something like this: ```python from q2_sdk.core import web async def test_func_to_be_tested(mock_success_class): ... monkeypatch.setattr('q2_sdk.core.web.ajax', mock_decorator) import importlib importlib.reload(web) actual = await handler.func_to_be_tested() assert isinstance(actual, type(mock_success)) ```
Hi Ethan, You have the right idea with mocking the decorator. In order for it to work, you could use monkeypatch to override the decorator with its mock and use importlib.reload to ensure that the changes are reflected (module caching appears to be the reason for which your mock isn't applying as expected. E.g You have a function that substracts 2 from a provided value, and a decorator defined in `mydecorator.py` that adds 4 to the value: ```python from mydecorator import add_four_decorator @add_four_decorator def subtract(a): return a - 2 ``` Mocking `add_four_decorator` in the unit test would look like the following: ```python from calculator import substract def do_nothing(func): def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper def test_calculator_subtract(monkeypatch): monkeypatch.setattr('mydecorator.add_four_decorator', do_nothing) import importlib importlib.reload(calculator) res = calculator.subtract(12) assert res == 10 ``` Above we are grabbing the monkeypatch fixture and using `monkeypatch.setattr` to pass in the <file_path>.<function_name> of the decorator, and the decorator to replace it with as the second parameter. We are then using importlib.relead to import the module again (rather than using the cached file) to ensure the mock is applied. The same idea would apply with ajax here and your test_func_to_be_tested would contain something like this: ```python async def test_func_to_be_tested(mock_success_class): ... monkeypatch.setattr('q2_sdk.core.web.ajax', mock_decorator) import importlib importlib.reload(calculator) actual = await handler.func_to_be_tested() assert isinstance(actual, type(mock_success)) ```
How can unit tests be written so that the "ajax" decorator does not interfere with testing?

Hi Ethan, You have the right idea with mocking the decorator. In order for it to work, you could use monkeypatch to override the decorator with its mock and use importlib.reload to ensure that the changes are reflected (module caching appears to be the reason for which your mock isn't applying as expected. E.g You have a function that substracts 2 from a provided value, and a decorator defined in `mydecorator.py` that adds 4 to the value: ```python from mydecorator import add_four_decorator @add_four_decorator def subtract(a): return a - 2 ``` Mocking `add_four_decorator` in the unit test would look like the following: ```python from calculator import substract def do_nothing(func): def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper def test_calculator_subtract(monkeypatch): monkeypatch.setattr('mydecorator.add_four_decorator', do_nothing) import importlib importlib.reload(calculator) res = calculator.subtract(12) assert res == 10 ``` Above we are grabbing the monkeypatch fixture and using `monkeypatch.setattr` to pass in the <file_path>.<function_name> of the decorator, and the decorator to replace it with as the second parameter. We are then using importlib.relead to import the module again (rather than using the cached file) to ensure the mock is applied. The same idea would apply with ajax here and your test_func_to_be_tested would contain something like this: ```python async def test_func_to_be_tested(mock_success_class): ... monkeypatch.setattr('q2_sdk.core.web.ajax', mock_decorator) import importlib importlib.reload(calculator) actual = await handler.func_to_be_tested() assert isinstance(actual, type(mock_success)) ```