2013-04-18 14 views
7

Zrobiłem dyrektywę, która służy do wyświetlania wiadomości powiadomień dla użytkownika. Aby wyświetlić powiadomienie, napisałem to:

$scope.$watch($messaging.isUpdated, function() { 
    $scope.messages = $messaging.getMessages(); 
    if ($scope.messages.length > 0) { 
     $timeout(function() { 
      for (var i = 0; i < $scope.messages.length; i++) { 
       if (i + 1 < $scope.messages.length) { 
        $messaging.removeMessage($scope.messages[i]); 
       } else { 
        $messaging.removeMessage($scope.messages[i]); 
       } 
      } 
     }, 5000); 
    } 
}); 

Używam $ timeout, aby upewnić się, że wiadomości pozostaną na ekranie przez 5 sekund.

Teraz chcę napisać test End-To-End na nim, aby upewnić się, że powiadomienie jest wyświetlane. Problem polega na tym, że po wyświetleniu powiadomienia termin End-to-End jest również przekroczony, podobnie jak komunikat powiadomienia. Dzięki temu nie można sprawdzić, czy wyświetlane jest właściwe powiadomienie. .

To jest mój kodu testu:

it('submit update Center', function() { 
    input('center.Name').enter('New Name'); 
    input('center.Department').enter('New Department'); 
    input('center.Contact').enter('New contact'); 
    input('center.Street').enter('New street'); 
    input('center.City').enter('New city'); 
    input('center.Country').enter('New Country'); 
    element('button#center_button').click(); 

    expect(element('.feedback').count()).toBe(1); 
    expect(element('.feedback:first').attr('class')).toMatch(/success/); 

    expect(element('.error.tooltip').count()).toBe(0); 
}); 

Chciałabym uniknąć używania javascript setTimeout() i mamy nadzieję, że jest inny (kątowe) rozwiązanie tego problemu.

+1

można zrobić to badanie jednostka zamiast, szydząc z '$ timeout' i sprawdzeniu, czy została ona wywołana z odpowiednimi argumentami? –

Odpowiedz

11

Złe wieści, kolego. Jest to znany problem w AngularJs. Istnieje dyskusja here i "jakoś pokrewny" tutaj issue.

szczęście, można obejść to przez walcowanie własnego $timeout usługę, nazywając setTimeout i nazywając $apply ręcznie (jest to propozycja z dyskusji ja, o którym mowa). To naprawdę proste, chociaż jest naprawdę brzydkie. Prosty przykład:

app.service('myTimeout', function($rootScope) { 
    return function(fn, delay) { 
    return setTimeout(function() { 
     fn(); 
     $rootScope.$apply(); 
    }, delay); 
    }; 
}); 

Uwaga ta nie jest zgodna z Kątowymi $timeout, ale można rozszerzyć funkcjonalność, jeśli trzeba.

0

malutka uwaga o ciebie if/else

$scope.$watch($messaging.isUpdated, function() { 
$scope.messages = $messaging.getMessages(); 
if ($scope.messages.length > 0) { 
    $timeout(function() { 
     for (var i = 0; i < $scope.messages.length; i++) { 
      if (i + 1 < $scope.messages.length) { 
       $messaging.removeMessage($scope.messages[i]); 
      } else { /**** unnecessay else here *****/ 
       $messaging.removeMessage($scope.messages[i]); 
      } 
     } 
    }, 5000); 
}}); 
Powiązane problemy