import unittest from unittest.mock import patch, MagicMock import sys import os # 添加项目根目录到Python路径 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) from hardware.relay import RelayController class TestRelayController(unittest.TestCase): def setUp(self): """测试前的准备工作""" self.relay_host = '192.168.0.18' self.relay_port = 50000 self.relay = RelayController(host=self.relay_host, port=self.relay_port) def test_relay_initialization(self): """测试继电器控制器初始化""" self.assertEqual(self.relay.host, self.relay_host) self.assertEqual(self.relay.port, self.relay_port) self.assertIsNotNone(self.relay.modbus_client) # 检查设备映射 self.assertIn(RelayController.DOOR_UPPER, self.relay.device_bit_map) self.assertIn(RelayController.DOOR_LOWER_1, self.relay.device_bit_map) self.assertIn(RelayController.DOOR_LOWER_2, self.relay.device_bit_map) self.assertIn(RelayController.BREAK_ARCH_UPPER, self.relay.device_bit_map) self.assertIn(RelayController.BREAK_ARCH_LOWER, self.relay.device_bit_map) @patch('hardware.relay.socket.socket') def test_send_command_success(self, mock_socket_class): """测试发送命令成功""" # 配置模拟对象 mock_socket_instance = MagicMock() mock_socket_class.return_value.__enter__.return_value = mock_socket_instance mock_socket_instance.recv.return_value = b'\x00\x00\x00\x00\x00\x06\x01\x01\x00\x00' # 发送命令 response = self.relay.send_command(self.relay.read_status_command) # 验证调用 mock_socket_instance.connect.assert_called_once_with((self.relay_host, self.relay_port)) mock_socket_instance.send.assert_called_once() self.assertIsNotNone(response) @patch('hardware.relay.socket.socket') def test_send_command_exception(self, mock_socket_class): """测试发送命令异常处理""" # 配置模拟对象以引发异常 mock_socket_class.return_value.__enter__.side_effect = Exception("网络错误") # 发送命令 response = self.relay.send_command(self.relay.read_status_command) # 验证结果 self.assertIsNone(response) def test_control_valid_device_action(self): """测试控制有效设备和动作""" with patch.object(self.relay, 'send_command') as mock_send: # 测试打开上料斗门 self.relay.control(RelayController.DOOR_UPPER, 'open') mock_send.assert_called_once() def test_control_invalid_device(self): """测试控制无效设备""" with patch.object(self.relay, 'send_command') as mock_send: # 测试无效设备 self.relay.control('invalid_device', 'open') mock_send.assert_not_called() def test_control_invalid_action(self): """测试控制无效动作""" with patch.object(self.relay, 'send_command') as mock_send: # 测试无效动作 self.relay.control(RelayController.DOOR_UPPER, 'invalid_action') mock_send.assert_not_called() @patch.object(RelayController, 'send_command') def test_get_status_success(self, mock_send_command): """测试获取状态成功""" # 模拟返回的有效响应 mock_send_command.return_value = b'\x00\x00\x00\x00\x00\x06\x01\x01\x00\x1F' status = self.relay.get_status() # 验证返回的状态字典 self.assertIsInstance(status, dict) self.assertIn(RelayController.DOOR_UPPER, status) mock_send_command.assert_called_once_with(self.relay.read_status_command) @patch.object(RelayController, 'send_command') def test_get_status_failure(self, mock_send_command): """测试获取状态失败""" # 模拟返回的无效响应 mock_send_command.return_value = None status = self.relay.get_status() # 验证返回空状态 self.assertIsInstance(status, dict) self.assertEqual(len(status), 0) if __name__ == '__main__': unittest.main()