Mock-objects are useful if you use external editor like VSCode or IDE like PyCharm, Eclipse and so on, because you can use DI (Dependency Injection) and you can debug your code logic with breakpoints.
For example, we want to add a cube on a scene:
You can read about this API function in the documentation: primitive_cube_add
- Create a work folder with the name: mock-object-for-primitive_cube_add-api
- Open Blender and safe project in the work folder
- Open "Scripting" tab in Blender from the top menu
- Open your favourite Python editor. I use VSCode. You can read about how to use VSCode with Python here Python in Visual Studio Code
- Create a file with the name "main.py" in you favourite Python editor. This file must be placed in the "mock-object-for-primitive_cube_add-api" folder
- Write in the "main.py":
print("hello from blender")
You can run this code from command line terminal or from VSCode internal terminal. Press in VSCode "Ctrl+`" and enter command:
You will see in the console terminal this message:
"hello from blender"
If you opened "Scripting" tab in Blender you will see an ability to open Python script in Blender.
- Click on the "Open" Button in Blender Script editor inside Blender
- Choose the "main.py" file and click the "Open Text Block" button
- Open the Blender console terminal. For this you need to select in the main menu of Blender "Window" and select "Toggle System Console"
- Run the "main.py" script from Blender. For this you need to place your mouse pointer on text area and press "Alt+P" button
- You will see this message in the Blender console terminal:
"hello from blender"
If you will change a code in an external editor like VSCode you need to reload in the Blender text editor. For this you need to press the "Alt+R+R" button
You need to add only one file: "main.py" to the Blender text editor. Another files you need place in the work directory: "mock-object-for-primitive_cube_add-api"
- Copy this code to the "main.py" file:
import bpy import sys import os # Get a path to the directory with .blend file # There are the scripts in this directory dir = os.path.dirname(bpy.data.filepath) # Is the directory in the list with included # directories? If no, include the directory if not dir in sys.path: sys.path.append(dir) import object3d_service # Reload module. It is necessary if you use # external editor like VSCode # For reloading module you need to press in # Blender: Alt + R + R import importlib importlib.reload(object3d_service) # Note. You do not need to open all scripts in Blender, # you need only this script from object3d_service import Object3DService def main(): objectService = Object3DService() objectService.create_cube() if __name__ == "__main__": main()
This is another files that you need to copy to the work directory:
import unittest from unittest.mock import MagicMock from object3d_service import Object3DService class BlenderServiceTest(unittest.TestCase): def test_myTest(self): # Arrange object3DService = Object3DService() object3DService.blender_api.create_cube = MagicMock("create_cube") # Act object3DService.create_cube() # Assert object3DService.blender_api.create_cube.assert_called_once()
from blender_api import BlenderAPI class Object3DService: def __init__(self): self.blender_api = BlenderAPI() def create_cube(self): self.blender_api.create_cube()
import bpy class BlenderAPI: def create_cube(self): bpy.ops.mesh.primitive_cube_add()
Delete a default cube from the scene. Now you can reload Blender code editor ("Alt+R+R") and run the code ("Alt + P"). You will see that a new code will be created:
You can set breakpoints in "main.py" because there are mock-object for Blender API. And you can run unit tests using this command:
python -m unittest
You will see that unit test are passed.