2010-10-06 42 views
9

Tôi đang cố gắng làm một bài kiểm tra đơn giản trong Python bằng cách sử dụng unittest, để xem nếu một lớp ném một ngoại lệ nếu nó nhận được một đầu vào không phù hợp cho hàm tạo. Lớp trông như thế này:Kiểm tra bằng Python - cách sử dụng assertRaises trong thử nghiệm bằng cách sử dụng unittest?

class SummaryFormula: 
    def __init__(self, summaryFormula): 
     self.atoms = {} 
     for atom in re.finditer("([A-Z][a-z]{0,2})(\d*)", summaryFormula): 
      symbol = atom.group(1) 
      count = atom.group(2) 

      if pocet != "": 
       self.atoms[ symbol] = int(count) 
      else: 
       self.atoms[ symbol] = 1 

thử nghiệm của tôi là như sau:

class ConstructorTestCase(unittest.TestCase): 
     def testEmptyString(self): 
     self.assertRaises(TypeError, ukol1.SummaryFormula(), "testtest") 

    if __name__ == '__main__': 
     unittest.main() 

Tất cả tôi muốn là thử nghiệm thất bại, có nghĩa là ngoại trừ đầu vào không phù hợp với nhà xây dựng không được xử lý.

Thay vào đó, tôi gặp lỗi: __init__() takes exactly 2 arguments (1 given).

Tôi đang thiếu gì? Đối số thứ hai tôi nên chỉ định là gì?

Ngoài ra, loại Lỗi nào tôi nên sử dụng để xử lý ngoại lệ mà đầu vào không khớp với regexp của tôi được chuyển cho hàm tạo?

Cảm ơn bạn, Tomas

+0

tôi không thể chạy mã trực tiếp vì có là lỗi cú pháp gần vòng lặp. Bạn có thể sửa nó. – pyfunc

+0

Tôi nghĩ rằng thụt đầu dòng xung quanh cho vòng lặp là không chính xác – pyfunc

+0

@pyfunc: Xin lỗi về điều đó. Sửa chữa nó. –

Trả lời

12

Thats vì lớp học của bạn đòi hỏi một tham số trong khi instantiating đối tượng

trong khi bạn đang đi qua

ukol1.SummaryFormula() 

bạn nên đã được đi qua các tham số summaryFormula với nó.

ukol1.SummaryFormula(someSummaryFormula) 

Ngoài ra sự nhầm lẫn là vì tên lớp của bạn là SummaryFormula và tham số mà bạn vượt qua để __init__ cũng là SummaryFormula

hay này nên

self.assertRaises(TypeError, ukol1.SummaryFormula, "testtest") 
+0

Điều này tất nhiên là điều đầu tiên mà tôi đã thử, nhưng nếu tôi sử dụng self.assertRaises (TypeError, ukol1.SummaryFormula ("testtest"), "testtest"), tôi gặp lỗi khác: SummaryFormula instance gas no __call__ method. Và không phải là bạn chỉ định các đối số được truyền cho hàm được kiểm tra trong assertRaises như là một đối số thứ ba (hoặc thứ tư, thứ năm, ...) của hàm assertRaises()? –

+1

@Tomas Novotny: Tôi đã thêm thay đổi thứ hai trong khi tôi đang cố chạy mã của bạn. Lặp lại nó ở đây: self.assertRaises (TypeError, ukol1.SummaryFormula, "testtest") – pyfunc

18

assertRaises là một chút bối rối, bởi vì bạn cần phải cho nó gọi, không phải là một biểu thức thực hiện cuộc gọi.

Thay đổi mã của bạn để:

self.assertRaises(TypeError, ukol1.SummaryFormula, "testtest") 

Trong code của bạn, bạn là cách gọi các nhà xây dựng chính mình, và nó đặt ra một ngoại lệ về việc không có đủ lý lẽ. Thay vào đó, bạn cần phải cung cấp cho assertRaises có thể gọi (ukol1.SummaryFormula) và các đối số để gọi nó bằng ("testtest"). Sau đó, nó có thể gọi nó, bắt và kiểm tra các trường hợp ngoại lệ.

2

Một định dạng thay thế hơn-generic là

args=['testtest'] 
kwargs = {} 
self.assertRaises(TypeError, ukol1.SummaryFormula, *args, **kwargs) 

này rất hữu ích nếu nhà xây dựng của bạn là đa hình và bạn muốn để lặp qua một danh sách các cách khác nhau của miswriting các đối số, ví dụ:

arg_lists = [ 
    ['testtest'], 
    ['anothertest'], 
    ['YAT'], 
] 
for args in arg_lists: 
    self.assertRaises(TypeError, ukol1.SummaryFormula, *args) 
0

Kể từ khi không có câu trả lời khác chỉ vào cách bạn có thể sử dụng bối cảnh đó đóng gói mã gây ra ngoại lệ, dưới đây là cách bạn có thể làm điều đó.

with self.assertRaises(ValueError) as ctx: 
    <some code that throws an exception> 

expected_msg = 'foo_bar_baz' 
self.assertEquals(ctx.exception.message, expected_msg) 

Thuộc tính quan tâm trong unittest.case._AssertRaisesContext này, bao gồm:

  • ngoại lệ
  • dự kiến ​​
  • expected_regexp
  • failureException
Các vấn đề liên quan