2012-01-19 48 views
36

Làm cách nào để giả lập đối tượng cửa sổ? Tôi đang làm phần mở rộng firefox và tôi muốn sử dụng hoa nhài để thử nghiệm javascript.đối tượng cửa sổ nhài hoa nhài

Trong javascript của tôi, tôi có

 

function submit() { 
... 
var url = window.arguments[0]; 
... 
} 
 

Rõ ràng, tôi phải thử window.arguments [0] trong hoa nhài vì đối tượng không tồn tại nếu không đi qua bất kỳ tham số từ window.openDialog

Đây là nỗ lực của tôi để thử nó với "với"

 

it("should submit to server", function() { 

     var localContext = { 
      "window": { 
       arguments: ["http://localhost"] 
      } 

     } 

     with(localContext); 
 

Nhưng tôi vẫn nhận được TypeError lỗi này: không thể đọc thuộc '0' không xác định, nó giống như khi thử nghiệm được chạy windo w.arguments [0] bị xóa sổ với cửa sổ thật, bởi vì nếu tôi làm

window.arguments[0]

bên trong kiểm tra, nó in ra "http: // localhost" một cách chính xác. nhưng khi nói đến phương thức submit() nó cho thấy lỗi window.argument là không xác định.

Trả lời

52

Vấn đề là bạn chỉ ghi đè lên một thuộc tính của đối tượng cửa sổ. Và nếu bạn có thể làm điều đó, trình duyệt cũng có thể làm điều đó. Vì vậy, chế nhạo một hàm hoặc thuộc tính của đối tượng chung mà mọi người có thể truy cập không phải là một ý tưởng hay nói chung, bởi vì bạn không bao giờ có thể chắc chắn rằng các thay đổi của bạn sẽ có khi bạn cố truy cập chúng.

Điều này đưa tôi đến dependency injection. Một mẫu chung của nó là làm cho đơn vị mã của bạn có thể kiểm tra được, với tiêu điểm là đơn vị. Có nghĩa là gì. Khi bạn tạo một đối tượng mới hoặc truy cập đối tượng toàn cục, bạn không chỉ thử nghiệm chức năng đơn vị mà còn là chức năng của đối tượng mới được tạo hoặc toàn cục của bạn. Để thêm vào đó, bạn không tạo các đối tượng mới trong đơn vị của bạn, nhưng chuyển chúng vào. Bình thường, bạn sẽ làm điều này trong hàm tạo, nhưng như trong hàm JavaScript là các đối tượng có phần thân hàm làm hàm tạo, bạn cũng có thể chuyển các hàm phụ thuộc vào hàm của bạn.

Vì vậy, trong trường hợp của bạn, hàm phụ thuộc vào đối tượng cửa sổ chung. Vì vậy, thay vì cố gắng truy cập đối tượng cửa sổ toàn cục, hãy chuyển nó làm tham số vào hàm của bạn. Làm theo cách này bạn có thể vượt qua trong các đối tượng cửa sổ trong mã sản xuất của bạn và một đối tượng JavaScript đơn giản với một đối số atribute vào thử nghiệm của bạn:

function youWannaTest(w){ 
    console.log(w.arguments[0]); 
} 

Trong phần mở rộng của bạn gọi hàm như thế này:

youWannaTest(window); 

Trong thử nghiệm, hãy gọi hàm như sau:

youWannaTest({arguments: ['someValue']}); 
+0

Cảm ơn bạn đã trả lời, vì vậy tôi không thể thử mà lên? – toy

+0

Cập nhật câu trả lời của tôi để làm cho điểm rõ ràng hơn một chút. –

1

Tôi cũng nghĩ rằng tiêm phụ thuộc là giải pháp sạch nhất.

JS của bạn:

function submit(_window) { 
    _window = _window || window 
    ... 
    var url = _window.arguments[0]; 
    ... 
} 

kiểm tra đơn vị của bạn:

it('works like a dream', function() { 
    var _window = { arguments: ['url'] } 
    expect(submit(_window)).toBeTotallyAwesome() 
}) 
0

Vâng, Bạn có thể chế nhạo đối tượng cửa sổ.

Điều đầu tiên bạn sẽ phải làm là thực hiện một thay đổi trong mã JS của bạn: Thay thế cửa sổ với $ sổ.

Sau đó, Bạn có thể thử sử dụng cửa sổ bên dưới mã:

var window = { 
    arguments : ['url'] 
}; 

bây giờ trong file spec của bạn: trong beforeEach chặn

$controller('controllerName', {$window : window}); 
Các vấn đề liên quan