未在Python模拟中执行断言

未在Python模拟中执行断言,python,python-2.7,unit-testing,python-mock,Python,Python 2.7,Unit Testing,Python Mock,我试图在我正在构建的一些代码上实现一些单元测试,但我看到了这种奇怪的行为,即即使我将函数调用的返回值设置为False,相关代码也不会执行,因此断言实例。fail\u json.assert\u调用了(msg='not ough parameters specified'))失败 还有什么我需要设置的吗 project.py: def main(): # define the available arguments/parameters that a user can pass #

我试图在我正在构建的一些代码上实现一些单元测试,但我看到了这种奇怪的行为,即即使我将函数调用的返回值设置为False,相关代码也不会执行,因此断言
实例。fail\u json.assert\u调用了(msg='not ough parameters specified'))
失败

还有什么我需要设置的吗

project.py:

def main():
   # define the available arguments/parameters that a user can pass
   # to the module
   module_args = dict(
      name=dict(type='str', required=True),
      ticktype=dict(type='str'),
      path=dict(type='str'),
      dbrp=dict(type='str'),
      state=dict(type='str', required=True, choices=["present", "absent"]),
      enable=dict(type='str', default="no", choices=["yes","no","da","net"])
   )

   required_if=[
      [ "state", "present", ["name", "type", "path", "dbrp", "enabled"] ],
      [ "state", "absent", ["name"]]
   ]

   # seed the result dict in the object
   # we primarily care about changed and state
   # change is if this module effectively modified the target
   # state will include any data that you want your module to pass back
   # for consumption, for exampole, in a subsequent task
   result = dict(
      changed=False,
      original_message='',
      message=''
   )

   # the AnsibleModule object will be our abstraction working with Ansible
   # this includes instantiation, a couple of common attr would be the
   # args/params passed to the execution, as well as if the module
   # supports check mode
   module = AnsibleModule(
      argument_spec=module_args,
      supports_check_mode=False
   )

   # if the user is working with this module in only check mode we do not
   # want to make any changes to the environment, just return the current
   # state with no modifications
   if module.check_mode:
      return result

   return_val = run_module(module)
   return_val = True
   if return_val is True:
      module.exit_json(changed=True, msg="Project updated.")
   else:
      module.fail_json(changed=True, msg="Not enough parameters found.")
@patch('library.project.run_module')
@patch('library.project.AnsibleModule')
def test_main_exit_functionality_failure(mock_module, mock_run_module):
   """
   project - test_main_exit_functionality - failure
   """
   instance = mock_module.return_value

   # What happens when the run_module returns false
   # that is run_module fails
   mock_run_module.return_value = False

   project.main()

   # AnsibleModule.exit_json should not activated
   assert_equals(instance.fail_json.call_count, 0)

   #AnsibleModule.fail_json should be called
   instance.fail_json.assert_called_with(msg='Not enough parameters 
   specified.')
test_project.py:

def main():
   # define the available arguments/parameters that a user can pass
   # to the module
   module_args = dict(
      name=dict(type='str', required=True),
      ticktype=dict(type='str'),
      path=dict(type='str'),
      dbrp=dict(type='str'),
      state=dict(type='str', required=True, choices=["present", "absent"]),
      enable=dict(type='str', default="no", choices=["yes","no","da","net"])
   )

   required_if=[
      [ "state", "present", ["name", "type", "path", "dbrp", "enabled"] ],
      [ "state", "absent", ["name"]]
   ]

   # seed the result dict in the object
   # we primarily care about changed and state
   # change is if this module effectively modified the target
   # state will include any data that you want your module to pass back
   # for consumption, for exampole, in a subsequent task
   result = dict(
      changed=False,
      original_message='',
      message=''
   )

   # the AnsibleModule object will be our abstraction working with Ansible
   # this includes instantiation, a couple of common attr would be the
   # args/params passed to the execution, as well as if the module
   # supports check mode
   module = AnsibleModule(
      argument_spec=module_args,
      supports_check_mode=False
   )

   # if the user is working with this module in only check mode we do not
   # want to make any changes to the environment, just return the current
   # state with no modifications
   if module.check_mode:
      return result

   return_val = run_module(module)
   return_val = True
   if return_val is True:
      module.exit_json(changed=True, msg="Project updated.")
   else:
      module.fail_json(changed=True, msg="Not enough parameters found.")
@patch('library.project.run_module')
@patch('library.project.AnsibleModule')
def test_main_exit_functionality_failure(mock_module, mock_run_module):
   """
   project - test_main_exit_functionality - failure
   """
   instance = mock_module.return_value

   # What happens when the run_module returns false
   # that is run_module fails
   mock_run_module.return_value = False

   project.main()

   # AnsibleModule.exit_json should not activated
   assert_equals(instance.fail_json.call_count, 0)

   #AnsibleModule.fail_json should be called
   instance.fail_json.assert_called_with(msg='Not enough parameters 
   specified.')

重新阅读您的生产代码。在检查返回值是否为真之前,它会在行上将返回值设置为真:

...

return_val = run_module(module)

return_val = True

if return_val is True:
    ...

return\u val
始终为真,无论
run\u module
返回什么,因此无论您在测试中执行什么操作,生产代码都将始终执行if-else检查的“true”分支。

这不是真的-在没有上下文的情况下读取代码非常困难。您应该非常仔细地阅读您的测试代码,以确保它所说的是您认为它所说的。我想主要的问题可能是最后一行。您必须将所有预期参数传递给
assert\u,并使用
调用。它应该读
instance.fail\u json.assert\u调用了(changed=True,msg='Not ough parameters specified.')
我将返回并更新代码以反映上述标准。但是,如果我将mock_run_模块的返回值设置为'False':
mock_run_模块。返回值=False
是否会导致if-else分支在main中执行False,从而随后运行module.fail_json(changed=True,msg=“未指定足够的参数”)?为什么它不运行是我的主要障碍<代码>如果返回值为True:module.exit_json(changed=True,msg=”“Project updated.”否则:module.fail_json(changed=True,msg=“未找到足够的参数”。