robotframework-mock 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robotframework-mock
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: A Robot Framework library for mocking keywords in unit tests
5
5
  Home-page: https://github.com/olesz/robotframework-mock
6
6
  Author: Lajos Olah
@@ -46,6 +46,7 @@ pip install -r requirements-dev.txt
46
46
  ## Features
47
47
 
48
48
  - Mock keywords from any Robot Framework library
49
+ - Mock keywords from Robot Framework resource files
49
50
  - Mock Robot Framework's BuiltIn keywords
50
51
  - Support for keywords with custom names via @keyword decorator
51
52
  - Verify keyword calls and call counts
@@ -119,6 +120,23 @@ Test Multiple Mocks
119
120
  MockReq.Reset Mocks
120
121
  ```
121
122
 
123
+ ### Mock Resource Keywords
124
+
125
+ Mock keywords from Robot Framework resource files:
126
+
127
+ ```robot
128
+ *** Settings ***
129
+ Resource my_resource.robot
130
+ Library MockResource my_resource.robot WITH NAME MockRes
131
+
132
+ *** Test Cases ***
133
+ Test Resource Keyword Mock
134
+ MockRes.Mock Keyword My Custom Keyword return_value=mocked_value
135
+ ${result}= My Custom Keyword
136
+ Should Be Equal ${result} mocked_value
137
+ MockRes.Reset Mocks
138
+ ```
139
+
122
140
  ## Keywords
123
141
 
124
142
  ### Mock Keyword
@@ -159,6 +177,8 @@ MockDB.Verify Keyword Called execute_sql times=1
159
177
 
160
178
  ## How It Works
161
179
 
180
+ ### MockLibrary
181
+
162
182
  MockLibrary dynamically replaces keyword implementations:
163
183
  1. Wraps the target library instance
164
184
  2. Resolves keyword names to function names (handles @keyword decorator)
@@ -168,11 +188,21 @@ MockLibrary dynamically replaces keyword implementations:
168
188
  6. Tracks call counts for verification
169
189
  7. Raises AttributeError if attempting to mock a non-existent keyword
170
190
 
191
+ ### MockResource
192
+
193
+ MockResource patches Robot Framework's keyword execution:
194
+ 1. Patches the Namespace.get_runner method
195
+ 2. Intercepts keyword execution for the specified resource file
196
+ 3. Replaces keyword body with Return statement containing mocked value
197
+ 4. Tracks call counts for verification
198
+ 5. Restores original keyword body on reset
199
+
171
200
  ## Notes
172
201
 
173
- - The library uses `ROBOT_LIBRARY_SCOPE = 'GLOBAL'` to maintain state across test cases
202
+ - Both libraries use `ROBOT_LIBRARY_SCOPE = 'GLOBAL'` to maintain state across test cases
174
203
  - Built on Python's unittest.mock.Mock for robust mocking capabilities
175
- - Supports any Robot Framework library, including BuiltIn
204
+ - MockLibrary supports any Robot Framework library, including BuiltIn
205
+ - MockResource works with resource files by patching the keyword execution pipeline
176
206
 
177
207
  ## License
178
208
 
@@ -1,179 +1,191 @@
1
- Metadata-Version: 2.4
2
- Name: robotframework-mock
3
- Version: 0.1.0
4
- Summary: A Robot Framework library for mocking keywords in unit tests
5
- Home-page: https://github.com/olesz/robotframework-mock
6
- Author: Lajos Olah
7
- Author-email: lajos.olah.jr@gmail.com
8
- License: Apache-2.0
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: Operating System :: OS Independent
11
- Classifier: Framework :: Robot Framework
12
- Classifier: Framework :: Robot Framework :: Library
13
- Requires-Python: >=3.7
14
- Description-Content-Type: text/markdown
15
- License-File: LICENSE
16
- Requires-Dist: robotframework>=7.0
17
- Dynamic: license-file
18
-
19
- # robotframework-mock
20
-
21
- A Robot Framework library for mocking keywords in unit tests.
22
-
23
- ## Installation
24
-
25
- ### From PyPI (once published)
26
-
27
- ```bash
28
- pip install robotframework-mock
29
- ```
30
-
31
- ### From source
32
-
33
- ```bash
34
- git clone https://github.com/yourusername/robotframework-mock.git
35
- cd robotframework-mock
36
- pip install .
37
- ```
38
-
39
- ### For development
40
-
41
- ```bash
42
- pip install -e .
43
- pip install -r requirements-dev.txt
44
- ```
45
-
46
- ## Features
47
-
48
- - Mock keywords from any Robot Framework library
49
- - Mock Robot Framework's BuiltIn keywords
50
- - Support for keywords with custom names via @keyword decorator
51
- - Verify keyword calls and call counts
52
- - Simple API with three main keywords
53
-
54
- ## Usage
55
-
56
- ### Mock Library Keywords
57
-
58
- Import the library you want to mock, then create a MockLibrary instance for it:
59
-
60
- ```robot
61
- *** Settings ***
62
- Library DatabaseLibrary
63
- Library MockLibrary DatabaseLibrary WITH NAME MockDB
64
-
65
- *** Test Cases ***
66
- Test With Mocked Keyword
67
- MockDB.Mock Keyword query return_value=test_data
68
- ${result}= DatabaseLibrary.Query SELECT * FROM users
69
- Should Be Equal ${result} test_data
70
- MockDB.Reset Mocks
71
- ```
72
-
73
- ### Verify Calls
74
-
75
- Verify that a keyword was called and optionally check the call count:
76
-
77
- ```robot
78
- *** Test Cases ***
79
- Test Keyword Was Called
80
- MockDB.Mock Keyword execute_sql return_value=${None}
81
- Process User Registration
82
- MockDB.Verify Keyword Called execute_sql times=1
83
- MockDB.Reset Mocks
84
- ```
85
-
86
- ### Mock BuiltIn Keywords
87
-
88
- Mock Robot Framework's built-in keywords using the same MockLibrary with "BuiltIn" as the library name:
89
-
90
- ```robot
91
- *** Settings ***
92
- Library MockLibrary BuiltIn WITH NAME MockBin
93
-
94
- *** Test Cases ***
95
- Test BuiltIn Mock
96
- MockBin.Mock Keyword Convert To Binary return_value=test_data
97
- ${result}= Convert To Binary aaa
98
- Should Be Equal ${result} test_data
99
- MockBin.Reset Mocks
100
- ```
101
-
102
- ### Mock Multiple Libraries
103
-
104
- You can mock multiple libraries in the same test:
105
-
106
- ```robot
107
- *** Settings ***
108
- Library DatabaseLibrary
109
- Library RequestsLibrary
110
- Library MockLibrary DatabaseLibrary WITH NAME MockDB
111
- Library MockLibrary RequestsLibrary WITH NAME MockReq
112
-
113
- *** Test Cases ***
114
- Test Multiple Mocks
115
- MockDB.Mock Keyword query return_value=user_data
116
- MockReq.Mock Keyword get return_value=api_response
117
- # Your test code here
118
- MockDB.Reset Mocks
119
- MockReq.Reset Mocks
120
- ```
121
-
122
- ## Keywords
123
-
124
- ### Mock Keyword
125
-
126
- Mock a keyword with a return value or side effect.
127
-
128
- **Arguments:**
129
- - `keyword_name` - Name of the keyword to mock
130
- - `return_value` - Value to return when called (optional)
131
- - `side_effect` - Callable to execute instead (optional)
132
-
133
- **Example:**
134
- ```robot
135
- MockDB.Mock Keyword query return_value=test_data
136
- ```
137
-
138
- ### Reset Mocks
139
-
140
- Restore all mocked keywords to their original implementations.
141
-
142
- **Example:**
143
- ```robot
144
- MockDB.Reset Mocks
145
- ```
146
-
147
- ### Verify Keyword Called
148
-
149
- Verify a keyword was called, optionally checking call count.
150
-
151
- **Arguments:**
152
- - `keyword_name` - Name of the keyword to verify
153
- - `times` - Expected number of calls (optional)
154
-
155
- **Example:**
156
- ```robot
157
- MockDB.Verify Keyword Called execute_sql times=1
158
- ```
159
-
160
- ## How It Works
161
-
162
- MockLibrary dynamically replaces keyword implementations:
163
- 1. Wraps the target library instance
164
- 2. Resolves keyword names to function names (handles @keyword decorator)
165
- 3. Stores original methods before mocking
166
- 4. Replaces methods with mock implementations using Python's unittest.mock.Mock
167
- 5. Returns mocked values or executes side effects
168
- 6. Tracks call counts for verification
169
- 7. Raises AttributeError if attempting to mock a non-existent keyword
170
-
171
- ## Notes
172
-
173
- - The library uses `ROBOT_LIBRARY_SCOPE = 'GLOBAL'` to maintain state across test cases
174
- - Built on Python's unittest.mock.Mock for robust mocking capabilities
175
- - Supports any Robot Framework library, including BuiltIn
176
-
177
- ## License
178
-
179
- See LICENSE file for details.
1
+ # robotframework-mock
2
+
3
+ A Robot Framework library for mocking keywords in unit tests.
4
+
5
+ ## Installation
6
+
7
+ ### From PyPI (once published)
8
+
9
+ ```bash
10
+ pip install robotframework-mock
11
+ ```
12
+
13
+ ### From source
14
+
15
+ ```bash
16
+ git clone https://github.com/yourusername/robotframework-mock.git
17
+ cd robotframework-mock
18
+ pip install .
19
+ ```
20
+
21
+ ### For development
22
+
23
+ ```bash
24
+ pip install -e .
25
+ pip install -r requirements-dev.txt
26
+ ```
27
+
28
+ ## Features
29
+
30
+ - Mock keywords from any Robot Framework library
31
+ - Mock keywords from Robot Framework resource files
32
+ - Mock Robot Framework's BuiltIn keywords
33
+ - Support for keywords with custom names via @keyword decorator
34
+ - Verify keyword calls and call counts
35
+ - Simple API with three main keywords
36
+
37
+ ## Usage
38
+
39
+ ### Mock Library Keywords
40
+
41
+ Import the library you want to mock, then create a MockLibrary instance for it:
42
+
43
+ ```robot
44
+ *** Settings ***
45
+ Library DatabaseLibrary
46
+ Library MockLibrary DatabaseLibrary WITH NAME MockDB
47
+
48
+ *** Test Cases ***
49
+ Test With Mocked Keyword
50
+ MockDB.Mock Keyword query return_value=test_data
51
+ ${result}= DatabaseLibrary.Query SELECT * FROM users
52
+ Should Be Equal ${result} test_data
53
+ MockDB.Reset Mocks
54
+ ```
55
+
56
+ ### Verify Calls
57
+
58
+ Verify that a keyword was called and optionally check the call count:
59
+
60
+ ```robot
61
+ *** Test Cases ***
62
+ Test Keyword Was Called
63
+ MockDB.Mock Keyword execute_sql return_value=${None}
64
+ Process User Registration
65
+ MockDB.Verify Keyword Called execute_sql times=1
66
+ MockDB.Reset Mocks
67
+ ```
68
+
69
+ ### Mock BuiltIn Keywords
70
+
71
+ Mock Robot Framework's built-in keywords using the same MockLibrary with "BuiltIn" as the library name:
72
+
73
+ ```robot
74
+ *** Settings ***
75
+ Library MockLibrary BuiltIn WITH NAME MockBin
76
+
77
+ *** Test Cases ***
78
+ Test BuiltIn Mock
79
+ MockBin.Mock Keyword Convert To Binary return_value=test_data
80
+ ${result}= Convert To Binary aaa
81
+ Should Be Equal ${result} test_data
82
+ MockBin.Reset Mocks
83
+ ```
84
+
85
+ ### Mock Multiple Libraries
86
+
87
+ You can mock multiple libraries in the same test:
88
+
89
+ ```robot
90
+ *** Settings ***
91
+ Library DatabaseLibrary
92
+ Library RequestsLibrary
93
+ Library MockLibrary DatabaseLibrary WITH NAME MockDB
94
+ Library MockLibrary RequestsLibrary WITH NAME MockReq
95
+
96
+ *** Test Cases ***
97
+ Test Multiple Mocks
98
+ MockDB.Mock Keyword query return_value=user_data
99
+ MockReq.Mock Keyword get return_value=api_response
100
+ # Your test code here
101
+ MockDB.Reset Mocks
102
+ MockReq.Reset Mocks
103
+ ```
104
+
105
+ ### Mock Resource Keywords
106
+
107
+ Mock keywords from Robot Framework resource files:
108
+
109
+ ```robot
110
+ *** Settings ***
111
+ Resource my_resource.robot
112
+ Library MockResource my_resource.robot WITH NAME MockRes
113
+
114
+ *** Test Cases ***
115
+ Test Resource Keyword Mock
116
+ MockRes.Mock Keyword My Custom Keyword return_value=mocked_value
117
+ ${result}= My Custom Keyword
118
+ Should Be Equal ${result} mocked_value
119
+ MockRes.Reset Mocks
120
+ ```
121
+
122
+ ## Keywords
123
+
124
+ ### Mock Keyword
125
+
126
+ Mock a keyword with a return value or side effect.
127
+
128
+ **Arguments:**
129
+ - `keyword_name` - Name of the keyword to mock
130
+ - `return_value` - Value to return when called (optional)
131
+ - `side_effect` - Callable to execute instead (optional)
132
+
133
+ **Example:**
134
+ ```robot
135
+ MockDB.Mock Keyword query return_value=test_data
136
+ ```
137
+
138
+ ### Reset Mocks
139
+
140
+ Restore all mocked keywords to their original implementations.
141
+
142
+ **Example:**
143
+ ```robot
144
+ MockDB.Reset Mocks
145
+ ```
146
+
147
+ ### Verify Keyword Called
148
+
149
+ Verify a keyword was called, optionally checking call count.
150
+
151
+ **Arguments:**
152
+ - `keyword_name` - Name of the keyword to verify
153
+ - `times` - Expected number of calls (optional)
154
+
155
+ **Example:**
156
+ ```robot
157
+ MockDB.Verify Keyword Called execute_sql times=1
158
+ ```
159
+
160
+ ## How It Works
161
+
162
+ ### MockLibrary
163
+
164
+ MockLibrary dynamically replaces keyword implementations:
165
+ 1. Wraps the target library instance
166
+ 2. Resolves keyword names to function names (handles @keyword decorator)
167
+ 3. Stores original methods before mocking
168
+ 4. Replaces methods with mock implementations using Python's unittest.mock.Mock
169
+ 5. Returns mocked values or executes side effects
170
+ 6. Tracks call counts for verification
171
+ 7. Raises AttributeError if attempting to mock a non-existent keyword
172
+
173
+ ### MockResource
174
+
175
+ MockResource patches Robot Framework's keyword execution:
176
+ 1. Patches the Namespace.get_runner method
177
+ 2. Intercepts keyword execution for the specified resource file
178
+ 3. Replaces keyword body with Return statement containing mocked value
179
+ 4. Tracks call counts for verification
180
+ 5. Restores original keyword body on reset
181
+
182
+ ## Notes
183
+
184
+ - Both libraries use `ROBOT_LIBRARY_SCOPE = 'GLOBAL'` to maintain state across test cases
185
+ - Built on Python's unittest.mock.Mock for robust mocking capabilities
186
+ - MockLibrary supports any Robot Framework library, including BuiltIn
187
+ - MockResource works with resource files by patching the keyword execution pipeline
188
+
189
+ ## License
190
+
191
+ See LICENSE file for details.
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = robotframework-mock
3
- version = 0.1.0
3
+ version = 0.2.0
4
4
  author = Lajos Olah
5
5
  author_email = lajos.olah.jr@gmail.com
6
6
  description = A Robot Framework library for mocking keywords in unit tests
@@ -6,10 +6,19 @@ from unittest.mock import Mock
6
6
  from robot.api.deco import keyword
7
7
  from robot.libraries.BuiltIn import BuiltIn
8
8
 
9
- __version__ = "1.0.0"
10
-
11
9
 
12
10
  def _get_library_instance(library_name_or_alias):
11
+ """Retrieve a library instance from Robot Framework's runtime.
12
+
13
+ Args:
14
+ library_name_or_alias: Name or alias of the library to retrieve
15
+
16
+ Returns:
17
+ The library instance object
18
+
19
+ Raises:
20
+ RuntimeError: If the library is not found in Robot Framework
21
+ """
13
22
  lib = BuiltIn().get_library_instance(library_name_or_alias)
14
23
  if not lib:
15
24
  raise RuntimeError(
@@ -34,8 +43,17 @@ class MockLibrary():
34
43
  ROBOT_LIBRARY_SCOPE = 'GLOBAL'
35
44
 
36
45
  def __init__(self, library_name_or_alias: str, lib: Any = None):
46
+ """Initialize MockLibrary with a target library to mock.
47
+
48
+ Args:
49
+ library_name_or_alias: Name or alias of the library to mock
50
+ lib: Optional library instance (for testing purposes)
51
+ """
52
+ # Store original method references before mocking
37
53
  self._original_methods = {}
54
+ # Store Mock objects for verification
38
55
  self._mocks = {}
56
+ # Get or set the library instance to mock
39
57
  if lib:
40
58
  self._library_instance = lib
41
59
  else:
@@ -48,17 +66,26 @@ class MockLibrary():
48
66
  ):
49
67
  """Mock a keyword from the wrapped library.
50
68
 
69
+ Args:
70
+ keyword_name: Name of the keyword to mock (case-insensitive)
71
+ return_value: Value to return when the keyword is called
72
+ side_effect: Callable to execute instead of returning a value
73
+
51
74
  Example:
52
75
  | MockDB.Mock Keyword | query | return_value=test_data |
53
76
  """
54
77
  lib = self._library_instance
78
+ # Convert keyword name to method name format (lowercase with underscores)
55
79
  method_name = keyword_name.lower().replace(' ', '_')
56
80
 
81
+ # Only store original method once per keyword
57
82
  if method_name not in self._original_methods:
58
83
  original_method = None
84
+ # Try direct attribute lookup first
59
85
  try:
60
86
  original_method = getattr(lib, method_name)
61
87
  except AttributeError:
88
+ # If not found, search for methods with @keyword decorator custom names
62
89
  for name, method in inspect.getmembers(
63
90
  lib, inspect.ismethod
64
91
  ):
@@ -67,36 +94,47 @@ class MockLibrary():
67
94
  original_method = getattr(lib, name)
68
95
  method_name = name
69
96
  break
97
+ # Raise error if keyword doesn't exist
70
98
  if not original_method:
71
99
  raise AttributeError(f"Keyword '{keyword_name}' not found in {lib}")
72
100
  self._original_methods[method_name] = original_method
73
101
 
102
+ # Create Mock object with specified behavior
74
103
  mock = Mock(return_value=return_value, side_effect=side_effect)
75
104
  self._mocks[method_name] = mock
76
105
 
106
+ # Replace the method on the class or instance
77
107
  try:
108
+ # Try to set on the class for bound methods
78
109
  owner_class = self._original_methods[method_name].__self__.__class__
79
110
  setattr(owner_class, method_name, mock)
80
111
  except AttributeError:
112
+ # Fall back to setting on the instance
81
113
  setattr(lib, method_name, mock)
82
114
 
83
-
84
115
  return mock
85
116
 
86
117
  @keyword
87
118
  def reset_mocks(self):
88
119
  """Reset all mocks to their original implementations.
89
120
 
121
+ Restores all mocked keywords to their original behavior and clears
122
+ all tracking data.
123
+
90
124
  Example:
91
125
  | MockDB.Reset Mocks |
92
126
  """
127
+ # Restore each mocked method to its original implementation
93
128
  for method_name, original_method in self._original_methods.items():
94
129
  try:
130
+ # Restore on the class for bound methods
95
131
  owner_class = original_method.__self__.__class__
96
132
  setattr(owner_class, method_name, original_method)
97
133
  except AttributeError:
134
+ # Restore on the instance
98
135
  setattr(self._library_instance, method_name, original_method)
99
136
 
137
+ # Clear all tracking dictionaries
100
138
  self._mocks.clear()
101
139
  self._original_methods.clear()
102
140
 
@@ -104,13 +142,23 @@ class MockLibrary():
104
142
  def verify_keyword_called(self, keyword_name: str, times: int = None):
105
143
  """Verify that a mocked keyword was called.
106
144
 
145
+ Args:
146
+ keyword_name: Name of the keyword to verify
147
+ times: Expected number of calls (optional, if None just checks it was called)
148
+
149
+ Raises:
150
+ AssertionError: If keyword was not mocked or call count doesn't match
151
+
107
152
  Example:
108
153
  | MockDB.Verify Keyword Called | execute_sql | times=1 |
109
154
  """
155
+ # Convert keyword name to method name format
110
156
  method_name = keyword_name.lower().replace(' ', '_')
157
+ # Check if the keyword was mocked
111
158
  if method_name not in self._mocks:
112
159
  raise AssertionError(f"Keyword '{keyword_name}' was not mocked")
113
160
 
161
+ # Verify call count if specified
114
162
  mock = self._mocks[method_name]
115
163
  if times is not None and mock.call_count != times:
116
164
  raise AssertionError(f"Expected {times} calls, got {mock.call_count}")
@@ -0,0 +1,113 @@
1
+ """Mock resource for Robot Framework keyword mocking in unit tests."""
2
+ # pylint: disable=invalid-name
3
+ from typing import Any, Callable
4
+ from unittest.mock import Mock
5
+
6
+ from robot.api.deco import keyword
7
+ from robot.libraries.BuiltIn import BuiltIn
8
+ from robot.running import Return
9
+ from robot.running.namespace import Namespace
10
+
11
+
12
+ class MockResource:
13
+ """Mock keywords from Robot Framework resource files for unit testing.
14
+
15
+ Example:
16
+ | Library | MockResource | my_resource.robot | WITH NAME | MockRes |
17
+ | MockRes.Mock Keyword | My Keyword | return_value=test_data |
18
+ | My Keyword |
19
+ | MockRes.Reset Mocks |
20
+ """
21
+
22
+ def __init__(self, source):
23
+ self._source = source
24
+ self._original_get_runner = Namespace.get_runner
25
+ self._original_items = {}
26
+ self._mocks = {}
27
+ self._install_patch()
28
+
29
+ def _install_patch(self):
30
+ original_get_runner = self._original_get_runner
31
+ active_mocks = self._mocks
32
+ source = self._source
33
+
34
+ def patched_get_runner(self, keyword_name, recommend_on_failure):
35
+ keyword_runner = original_get_runner(self, keyword_name, recommend_on_failure)
36
+ resource_file = getattr(keyword_runner.keyword, "source", None)
37
+
38
+ if source not in str(resource_file):
39
+ return keyword_runner
40
+
41
+ mock = active_mocks.get(keyword_name)
42
+ if mock:
43
+ original_run = keyword_runner.run
44
+ def patched_run(data, result, context, run):
45
+ mock_result = mock(data.args)
46
+ keyword_runner.keyword.body._items = [Return(values=[mock_result])] # pylint: disable=protected-access
47
+ return original_run(data, result, context, run)
48
+ keyword_runner.run = patched_run
49
+
50
+ return keyword_runner
51
+
52
+ Namespace.get_runner = patched_get_runner
53
+
54
+ @keyword
55
+ def mock_keyword(
56
+ self, keyword_name: str,
57
+ return_value: Any = None, side_effect: Callable = None
58
+ ):
59
+ """Mock a keyword from the resource file.
60
+
61
+ Args:
62
+ keyword_name: Name of the keyword to mock
63
+ return_value: Value to return when the keyword is called
64
+ side_effect: Callable to execute instead of returning a value
65
+
66
+ Example:
67
+ | MockRes.Mock Keyword | My Keyword | return_value=test_data |
68
+ """
69
+ keyword_runner = BuiltIn()._namespace.get_runner(keyword_name, True) # pylint: disable=protected-access
70
+ resource_file = getattr(keyword_runner.keyword, "source", None)
71
+
72
+ if self._source not in str(resource_file):
73
+ raise AttributeError("fKeyword '{keyword_name}' not found in {self._source}")
74
+
75
+ self._original_items[keyword_name] = keyword_runner.keyword.body._items # pylint: disable=protected-access
76
+ mock = Mock(return_value=return_value, side_effect=side_effect)
77
+ self._mocks[keyword_name] = mock
78
+
79
+ @keyword
80
+ def reset_mocks(self):
81
+ """Reset all mocks to their original implementations.
82
+
83
+ Restores all mocked keywords to their original behavior.
84
+
85
+ Example:
86
+ | MockRes.Reset Mocks |
87
+ """
88
+ self._mocks.clear()
89
+ for keyword_name, items in self._original_items.items():
90
+ keyword_runner = BuiltIn()._namespace.get_runner(keyword_name, True) # pylint: disable=protected-access
91
+ keyword_runner.keyword.body._items = items # pylint: disable=protected-access
92
+ self._original_items.clear()
93
+
94
+ @keyword
95
+ def verify_keyword_called(self, keyword_name: str, times: int = None):
96
+ """Verify that a mocked keyword was called.
97
+
98
+ Args:
99
+ keyword_name: Name of the keyword to verify
100
+ times: Expected number of calls (optional)
101
+
102
+ Raises:
103
+ AssertionError: If keyword was not mocked or call count doesn't match
104
+
105
+ Example:
106
+ | MockDB.Verify Keyword Called | Execute Sql | times=1 |
107
+ """
108
+ if keyword_name not in self._mocks:
109
+ raise AssertionError(f"Keyword '{keyword_name}' was not mocked")
110
+
111
+ mock = self._mocks[keyword_name]
112
+ if times is not None and mock.call_count != times:
113
+ raise AssertionError(f"Expected {times} calls, got {mock.call_count}")
@@ -1,161 +1,209 @@
1
- # robotframework-mock
2
-
3
- A Robot Framework library for mocking keywords in unit tests.
4
-
5
- ## Installation
6
-
7
- ### From PyPI (once published)
8
-
9
- ```bash
10
- pip install robotframework-mock
11
- ```
12
-
13
- ### From source
14
-
15
- ```bash
16
- git clone https://github.com/yourusername/robotframework-mock.git
17
- cd robotframework-mock
18
- pip install .
19
- ```
20
-
21
- ### For development
22
-
23
- ```bash
24
- pip install -e .
25
- pip install -r requirements-dev.txt
26
- ```
27
-
28
- ## Features
29
-
30
- - Mock keywords from any Robot Framework library
31
- - Mock Robot Framework's BuiltIn keywords
32
- - Support for keywords with custom names via @keyword decorator
33
- - Verify keyword calls and call counts
34
- - Simple API with three main keywords
35
-
36
- ## Usage
37
-
38
- ### Mock Library Keywords
39
-
40
- Import the library you want to mock, then create a MockLibrary instance for it:
41
-
42
- ```robot
43
- *** Settings ***
44
- Library DatabaseLibrary
45
- Library MockLibrary DatabaseLibrary WITH NAME MockDB
46
-
47
- *** Test Cases ***
48
- Test With Mocked Keyword
49
- MockDB.Mock Keyword query return_value=test_data
50
- ${result}= DatabaseLibrary.Query SELECT * FROM users
51
- Should Be Equal ${result} test_data
52
- MockDB.Reset Mocks
53
- ```
54
-
55
- ### Verify Calls
56
-
57
- Verify that a keyword was called and optionally check the call count:
58
-
59
- ```robot
60
- *** Test Cases ***
61
- Test Keyword Was Called
62
- MockDB.Mock Keyword execute_sql return_value=${None}
63
- Process User Registration
64
- MockDB.Verify Keyword Called execute_sql times=1
65
- MockDB.Reset Mocks
66
- ```
67
-
68
- ### Mock BuiltIn Keywords
69
-
70
- Mock Robot Framework's built-in keywords using the same MockLibrary with "BuiltIn" as the library name:
71
-
72
- ```robot
73
- *** Settings ***
74
- Library MockLibrary BuiltIn WITH NAME MockBin
75
-
76
- *** Test Cases ***
77
- Test BuiltIn Mock
78
- MockBin.Mock Keyword Convert To Binary return_value=test_data
79
- ${result}= Convert To Binary aaa
80
- Should Be Equal ${result} test_data
81
- MockBin.Reset Mocks
82
- ```
83
-
84
- ### Mock Multiple Libraries
85
-
86
- You can mock multiple libraries in the same test:
87
-
88
- ```robot
89
- *** Settings ***
90
- Library DatabaseLibrary
91
- Library RequestsLibrary
92
- Library MockLibrary DatabaseLibrary WITH NAME MockDB
93
- Library MockLibrary RequestsLibrary WITH NAME MockReq
94
-
95
- *** Test Cases ***
96
- Test Multiple Mocks
97
- MockDB.Mock Keyword query return_value=user_data
98
- MockReq.Mock Keyword get return_value=api_response
99
- # Your test code here
100
- MockDB.Reset Mocks
101
- MockReq.Reset Mocks
102
- ```
103
-
104
- ## Keywords
105
-
106
- ### Mock Keyword
107
-
108
- Mock a keyword with a return value or side effect.
109
-
110
- **Arguments:**
111
- - `keyword_name` - Name of the keyword to mock
112
- - `return_value` - Value to return when called (optional)
113
- - `side_effect` - Callable to execute instead (optional)
114
-
115
- **Example:**
116
- ```robot
117
- MockDB.Mock Keyword query return_value=test_data
118
- ```
119
-
120
- ### Reset Mocks
121
-
122
- Restore all mocked keywords to their original implementations.
123
-
124
- **Example:**
125
- ```robot
126
- MockDB.Reset Mocks
127
- ```
128
-
129
- ### Verify Keyword Called
130
-
131
- Verify a keyword was called, optionally checking call count.
132
-
133
- **Arguments:**
134
- - `keyword_name` - Name of the keyword to verify
135
- - `times` - Expected number of calls (optional)
136
-
137
- **Example:**
138
- ```robot
139
- MockDB.Verify Keyword Called execute_sql times=1
140
- ```
141
-
142
- ## How It Works
143
-
144
- MockLibrary dynamically replaces keyword implementations:
145
- 1. Wraps the target library instance
146
- 2. Resolves keyword names to function names (handles @keyword decorator)
147
- 3. Stores original methods before mocking
148
- 4. Replaces methods with mock implementations using Python's unittest.mock.Mock
149
- 5. Returns mocked values or executes side effects
150
- 6. Tracks call counts for verification
151
- 7. Raises AttributeError if attempting to mock a non-existent keyword
152
-
153
- ## Notes
154
-
155
- - The library uses `ROBOT_LIBRARY_SCOPE = 'GLOBAL'` to maintain state across test cases
156
- - Built on Python's unittest.mock.Mock for robust mocking capabilities
157
- - Supports any Robot Framework library, including BuiltIn
158
-
159
- ## License
160
-
161
- See LICENSE file for details.
1
+ Metadata-Version: 2.4
2
+ Name: robotframework-mock
3
+ Version: 0.2.0
4
+ Summary: A Robot Framework library for mocking keywords in unit tests
5
+ Home-page: https://github.com/olesz/robotframework-mock
6
+ Author: Lajos Olah
7
+ Author-email: lajos.olah.jr@gmail.com
8
+ License: Apache-2.0
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Framework :: Robot Framework
12
+ Classifier: Framework :: Robot Framework :: Library
13
+ Requires-Python: >=3.7
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: robotframework>=7.0
17
+ Dynamic: license-file
18
+
19
+ # robotframework-mock
20
+
21
+ A Robot Framework library for mocking keywords in unit tests.
22
+
23
+ ## Installation
24
+
25
+ ### From PyPI (once published)
26
+
27
+ ```bash
28
+ pip install robotframework-mock
29
+ ```
30
+
31
+ ### From source
32
+
33
+ ```bash
34
+ git clone https://github.com/yourusername/robotframework-mock.git
35
+ cd robotframework-mock
36
+ pip install .
37
+ ```
38
+
39
+ ### For development
40
+
41
+ ```bash
42
+ pip install -e .
43
+ pip install -r requirements-dev.txt
44
+ ```
45
+
46
+ ## Features
47
+
48
+ - Mock keywords from any Robot Framework library
49
+ - Mock keywords from Robot Framework resource files
50
+ - Mock Robot Framework's BuiltIn keywords
51
+ - Support for keywords with custom names via @keyword decorator
52
+ - Verify keyword calls and call counts
53
+ - Simple API with three main keywords
54
+
55
+ ## Usage
56
+
57
+ ### Mock Library Keywords
58
+
59
+ Import the library you want to mock, then create a MockLibrary instance for it:
60
+
61
+ ```robot
62
+ *** Settings ***
63
+ Library DatabaseLibrary
64
+ Library MockLibrary DatabaseLibrary WITH NAME MockDB
65
+
66
+ *** Test Cases ***
67
+ Test With Mocked Keyword
68
+ MockDB.Mock Keyword query return_value=test_data
69
+ ${result}= DatabaseLibrary.Query SELECT * FROM users
70
+ Should Be Equal ${result} test_data
71
+ MockDB.Reset Mocks
72
+ ```
73
+
74
+ ### Verify Calls
75
+
76
+ Verify that a keyword was called and optionally check the call count:
77
+
78
+ ```robot
79
+ *** Test Cases ***
80
+ Test Keyword Was Called
81
+ MockDB.Mock Keyword execute_sql return_value=${None}
82
+ Process User Registration
83
+ MockDB.Verify Keyword Called execute_sql times=1
84
+ MockDB.Reset Mocks
85
+ ```
86
+
87
+ ### Mock BuiltIn Keywords
88
+
89
+ Mock Robot Framework's built-in keywords using the same MockLibrary with "BuiltIn" as the library name:
90
+
91
+ ```robot
92
+ *** Settings ***
93
+ Library MockLibrary BuiltIn WITH NAME MockBin
94
+
95
+ *** Test Cases ***
96
+ Test BuiltIn Mock
97
+ MockBin.Mock Keyword Convert To Binary return_value=test_data
98
+ ${result}= Convert To Binary aaa
99
+ Should Be Equal ${result} test_data
100
+ MockBin.Reset Mocks
101
+ ```
102
+
103
+ ### Mock Multiple Libraries
104
+
105
+ You can mock multiple libraries in the same test:
106
+
107
+ ```robot
108
+ *** Settings ***
109
+ Library DatabaseLibrary
110
+ Library RequestsLibrary
111
+ Library MockLibrary DatabaseLibrary WITH NAME MockDB
112
+ Library MockLibrary RequestsLibrary WITH NAME MockReq
113
+
114
+ *** Test Cases ***
115
+ Test Multiple Mocks
116
+ MockDB.Mock Keyword query return_value=user_data
117
+ MockReq.Mock Keyword get return_value=api_response
118
+ # Your test code here
119
+ MockDB.Reset Mocks
120
+ MockReq.Reset Mocks
121
+ ```
122
+
123
+ ### Mock Resource Keywords
124
+
125
+ Mock keywords from Robot Framework resource files:
126
+
127
+ ```robot
128
+ *** Settings ***
129
+ Resource my_resource.robot
130
+ Library MockResource my_resource.robot WITH NAME MockRes
131
+
132
+ *** Test Cases ***
133
+ Test Resource Keyword Mock
134
+ MockRes.Mock Keyword My Custom Keyword return_value=mocked_value
135
+ ${result}= My Custom Keyword
136
+ Should Be Equal ${result} mocked_value
137
+ MockRes.Reset Mocks
138
+ ```
139
+
140
+ ## Keywords
141
+
142
+ ### Mock Keyword
143
+
144
+ Mock a keyword with a return value or side effect.
145
+
146
+ **Arguments:**
147
+ - `keyword_name` - Name of the keyword to mock
148
+ - `return_value` - Value to return when called (optional)
149
+ - `side_effect` - Callable to execute instead (optional)
150
+
151
+ **Example:**
152
+ ```robot
153
+ MockDB.Mock Keyword query return_value=test_data
154
+ ```
155
+
156
+ ### Reset Mocks
157
+
158
+ Restore all mocked keywords to their original implementations.
159
+
160
+ **Example:**
161
+ ```robot
162
+ MockDB.Reset Mocks
163
+ ```
164
+
165
+ ### Verify Keyword Called
166
+
167
+ Verify a keyword was called, optionally checking call count.
168
+
169
+ **Arguments:**
170
+ - `keyword_name` - Name of the keyword to verify
171
+ - `times` - Expected number of calls (optional)
172
+
173
+ **Example:**
174
+ ```robot
175
+ MockDB.Verify Keyword Called execute_sql times=1
176
+ ```
177
+
178
+ ## How It Works
179
+
180
+ ### MockLibrary
181
+
182
+ MockLibrary dynamically replaces keyword implementations:
183
+ 1. Wraps the target library instance
184
+ 2. Resolves keyword names to function names (handles @keyword decorator)
185
+ 3. Stores original methods before mocking
186
+ 4. Replaces methods with mock implementations using Python's unittest.mock.Mock
187
+ 5. Returns mocked values or executes side effects
188
+ 6. Tracks call counts for verification
189
+ 7. Raises AttributeError if attempting to mock a non-existent keyword
190
+
191
+ ### MockResource
192
+
193
+ MockResource patches Robot Framework's keyword execution:
194
+ 1. Patches the Namespace.get_runner method
195
+ 2. Intercepts keyword execution for the specified resource file
196
+ 3. Replaces keyword body with Return statement containing mocked value
197
+ 4. Tracks call counts for verification
198
+ 5. Restores original keyword body on reset
199
+
200
+ ## Notes
201
+
202
+ - Both libraries use `ROBOT_LIBRARY_SCOPE = 'GLOBAL'` to maintain state across test cases
203
+ - Built on Python's unittest.mock.Mock for robust mocking capabilities
204
+ - MockLibrary supports any Robot Framework library, including BuiltIn
205
+ - MockResource works with resource files by patching the keyword execution pipeline
206
+
207
+ ## License
208
+
209
+ See LICENSE file for details.
@@ -5,6 +5,7 @@ pyproject.toml
5
5
  setup.cfg
6
6
  setup.py
7
7
  src/MockLibrary/__init__.py
8
+ src/MockResource/__init__.py
8
9
  src/robotframework_mock.egg-info/PKG-INFO
9
10
  src/robotframework_mock.egg-info/SOURCES.txt
10
11
  src/robotframework_mock.egg-info/dependency_links.txt
@@ -0,0 +1,2 @@
1
+ MockLibrary
2
+ MockResource