attributeError(“'_ AssertRaisesContext'对象没有属性'exception'”,),

时间:2017-02-24 20:35:11

标签: python

我是python中的初学者编码。我真的不明白这个错误是指什么。任何帮助将不胜感激。 该代码应该计算某个国家/地区的人们的税收如下: 每年收入:0 - 1000

税率:0%

年收入:1,001 - 10,000

税率:10%

年收入:10,001 - 20,200

税率:15%

年收入:20,201 - 30,750

税率:20%

每年收入:30,751 - 50,000

税率:25%

年收入:超过50,000

税率:30%

我的代码:

def calculate_tax(pDict):
  if type(pDict) is dict:
    try:
      length = len(pDict)
      count = 0
      #decleration of new updated dictionary
      dict_list = {}
      while count<length:
        #calculate yearly tax
        #countdown of values in the dictionary until the last value
        totals = list(pDict.values())[count]
        totals = int(totals)
        names = list(pDict.keys())[count]
        #decleration of variable to store tax
        tTax = 0
        if totals < 1000:
          tTax = totals * 0
        elif totals > 1000 and totals<= 10000:
          tTax = 1000 * 0
          totals = totals - 1000
          tTax = tTax + totals * 0.1
        elif totals > 10000 and totals <=20200:
          tTax = 1000 * 0
          tTax = tTax + 9000 * 0.1
          totals=totals-10000
          tTax = tTax + totals * 0.15
        elif totals >20200 and totals <= 30750:
          tTax = 1000 * 0
          tTax = tTax + 9000 * 0.1
          tTax = tTax + 10200 * 0.15
          totals=totals-20200
          tTax = tTax + totals * 0.2
        elif totals>30750 and totals<=50000:
          tTax = 1000 * 0
          tTax = tTax + 9000 * 0.1
          tTax = tTax + 10200 * 0.15
          tTax = tTax + 10550 * 0.2
          totals=totals-30750
          tTax = tTax + totals * 0.25
        else:
          tTax = 1000 * 0
          tTax = tTax + 9000 * 0.1
          tTax = tTax + 10200 * 0.15
          tTax = tTax + 10550 * 0.2
          tTax = tTax + 19250 * 0.25
          totals=totals-50000
          tTax = tTax + totals * 0.3
        dict_list.setdefault(names,tTax)
        count = count + 1
      return dict_list
    except(attributeError,TypeError):
      raise ValueError('The provided input is not a dictionary')
  else:
    print("only dict type values allowed")

用于测试我的代码是否有效的代码:

from unittest import TestCase

    class CalculateTaxTests(TestCase):
      def test_it_calculates_tax_for_one_person(self):
        result = calculate_tax({"James": 20500})
        self.assertEqual(result, {"James": 2490.0}, msg="Should return {'James': 2490.0} for the input {'James': 20500}")

      def test_it_calculates_tax_for_several_people(self):
        income_input = {"James": 20500, "Mary": 500, "Evan": 70000}
        result = calculate_tax(income_input)
        self.assertEqual({"James": 2490.0, "Mary": 0, "Evan": 15352.5}, result,
          msg="Should return {} for the input {}".format(
                {"James": 2490.0, "Mary": 0, "Evan": 15352.5},
                {"James": 20500, "Mary": 500, "Evan": 70000}
          )
        )

      def test_it_does_not_accept_integers(self):
        with self.assertRaises(ValueError) as context:
          calculate_tax(1)
          self.assertEqual(
            "The provided input is not a dictionary.",
            context.exception.message, "Invalid input of type int not allowed"
          )

      def test_calculated_tax_is_a_float(self):
        result = calculate_tax({"Jane": 20500})
        self.assertIsInstance(
          calculate_tax({"Jane": 20500}), dict, msg="Should return a result of data type dict")
        self.assertIsInstance(result["Jane"], float, msg="Tax returned should be an float.")

      def test_it_returns_zero_tax_for_income_less_than_1000(self):
        result = calculate_tax({"Jake": 100})
        self.assertEqual(result, {"Jake": 0}, msg="Should return zero tax for incomes less than 1000")

      def test_it_throws_an_error_if_any_of_the_inputs_is_non_numeric(self):
        with self.assertRaises(ValueError, msg='Allow only numeric input'):
          calculate_tax({"James": 2490.0, "Kiura": '200', "Kinuthia": 15352.5})

      def test_it_return_an_empty_dict_for_an_empty_dict_input(self):
        result = calculate_tax({})
        self.assertEqual(result, {}, msg='Should return an empty dict if the input was an empty dict')

请帮助: - )

1 个答案:

答案 0 :(得分:7)

作为参考,失败测试的完整异常消息如下:

ERROR: test_it_does_not_accept_integers (__main__.CalculateTaxTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "calculate_tax_test.py", line 27, in test_it_does_not_accept_integers
    context.exception.message, "Invalid input of type int not allowed"
AttributeError: '_AssertRaisesContext' object has no attribute 'exception'

失败的测试是这样的:

      def test_it_does_not_accept_integers(self):
        with self.assertRaises(ValueError) as context:
          calculate_tax(1)
          self.assertEqual(
            "The provided input is not a dictionary.",
            context.exception.message, "Invalid input of type int not allowed"
          )

问题是calculate_tax之后的断言位于错误的位置。如果在calculate_tax中引发异常,则将跳过断言。如果没有引发异常,则断言将失败。因此断言永远不会过去。

修复是取消缩进断言以将其移出with语句。为清楚起见,我还插入了一个空行:

      def test_it_does_not_accept_integers(self):
        with self.assertRaises(ValueError) as context:
          calculate_tax(1)

        self.assertEqual(
          "The provided input is not a dictionary.",
          context.exception.message, "Invalid input of type int not allowed"
        )

with self.assertRaises(...)语句可以通过调用calculate_tax引发异常。如果发生这种情况,则会在context中保留异常详细信息,然后您的断言将能够测试异常是否符合您的预期。

但是,即使进行此更改后,测试仍然失败,因为calculate_tax(1)没有引发ValueError。我会告诉你解决这个问题。