JavaScript es un lenguaje de tipo dinámico, que le brinda una fuerte capacidad de rendimiento, pero también hace que el compilador sea casi imposible proporcionar ayuda a los desarrolladores. Por esta razón, creemos que escribir cualquier código JavaScript debe tener un conjunto de pruebas potente y completo. Angular tiene muchas características que nos facilitan probar nuestras aplicaciones. No deberíamos tener ninguna excusa para no escribir pruebas (esto es todo ...).
1. Se trata de no mezclar preocupaciones (se trata de evitar que la relación del código se vuelva complicada ...)
La prueba unitaria, como nombre, se trata de probar una sola "unidad". La prueba unitaria se esfuerza por responder a estas preguntas: ¿Ya estoy en lo correcto en mis consideraciones lógicas? ¿Son correctos los resultados obtenidos por el método de clasificación? Para responder a estas preguntas, es particularmente importante separarlas. Esto se debe a que cuando estamos probando el método de clasificación, no queremos preocuparnos por otros fragmentos relacionados, como elementos DOM o iniciar solicitudes de XHR para obtener datos, etc. Obviamente, generalmente es difícil llamar a una función por separado en un proyecto típico. La razón de este problema es que los desarrolladores a menudo complican las relaciones y terminan haciendo que un fragmento parezca que puede hacer todo. Obtiene los datos a través de XHR, clasifica los datos y luego manipula el DOM. Junto con Angular podemos escribir un mejor código más fácilmente, por lo que Angular nos proporciona una inyección de dependencia de XHR (que podemos simular) y Angular también crea abstracciones que nos permiten ordenar el modelo sin tener que manipular el DOM. Entonces, al final, simplemente podemos escribir un método de clasificación y luego crear un conjunto de datos a través del caso de prueba para el método de clasificación que se utilizará al probar, y luego determinar si el modelo de resultados cumple con las expectativas. La prueba no requiere esperar que XHR cree el DOM correspondiente y determine si la función opera el DOM correctamente. La idea central de Angular incluye la capacidad de prueba del código, pero también requiere que hagamos lo correcto. Angular se compromete a simplificar la forma de hacer lo correcto, pero Angular no es mágico, lo que significa que podemos terminar con una aplicación no probable si no seguimos los siguientes puntos.
1. Inyección de dependencia
Hay muchas formas de obtener los recursos de dependencia: 1) podemos usar el nuevo operador; 2) utilizamos un método conocido llamado "Global Singleton"; 3) Podemos solicitarlo del servicio de registro (pero ¿cómo obtenemos un registro? Puede verificar los siguientes capítulos); 4) Podemos esperar que se pase.
De los métodos mencionados anteriormente, solo el último es comprobable, veamos por qué:
1) Uso del nuevo operador
Básicamente, no hay errores al usar el nuevo operador, pero el problema es que llamar al constructor a través de nuevo vinculará permanentemente la persona que llama al tipo. Por ejemplo, intentamos instanciar un objeto XHR para que podamos obtener algunos datos del servidor.
function myClass () {this.dowork = function () {var xhr = new xrh (); xhr.open (método, url, verdadero); xhr.OnreadyStateChange = function () {...}; xhr.send (); }}El problema es que al probar, generalmente necesitamos instanciar un XHR virtual que pueda devolver datos de prueba o errores de red. Al llamar a New XHR (), unimos permanentemente el XHR real y no hay una buena manera de reemplazarlo. Por supuesto, hay un mal remedio y hay muchas razones para demostrar que es una mala idea:
var Oldxhr = xhr; xhr = new Mockxhr () {}; myclass.dowork (); // juzga si Mockxhr llama xhr = Oldxhr a través de parámetros normales; // Si olvida este paso, es fácil causar cosas tristes.2) Búsqueda global
Otra forma de resolver el problema es obtener los recursos de dependencia en un lugar bien conocido.
function myClass () {this.dowork = function () {global.xhr ({...}); };}Sin crear una instancia de un nuevo objeto dependiente, el problema es básicamente el mismo que nuevo, y no hay una buena manera de interceptar llamadas Global.xHR al probar. El problema más básico con las pruebas es que las variables globales deben cambiarse para llamar a los métodos virtuales y se modifican. Para obtener más información sobre sus desventajas, visite aquí: http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/
El código anterior es difícil de probar, por lo que debemos modificar el estado global:
var Oldxhr = Global.xhr; Global.xhr = function Mockxhr () {...}; var myClass = new MyClass (); // juzga si Mockxhr llama global.xhr = Oldxhr a través de parámetros normales; // Si olvida este paso, es fácil causar cosas tristes.3) Registro de servicio
Tener un registro con todos los servicios parece resolver el problema y luego reemplazar el servicio requerido en el código de prueba.
function myClass () {var ServiceRegistry = ???; this.dowork = function () {var xhr = ServiceRegistry.get ("xhr"); …};}Pero, ¿de dónde viene el ServiceRegistry? Si es: * nuevo, la prueba no tiene la oportunidad de restablecer los servicios para probar * la búsqueda global, entonces el servicio devuelto también es global (pero restablecer es más fácil, ya que solo hay una variable global que se restablecerá) (el texto detrás aquí es el mismo que confuso ... no entendí)
De acuerdo con este método, modifique la clase anterior al siguiente método:
var OldServiceLocator = Global.ServiceLocator; Global.ServiceLocator.set ('xhr', function Mockxhr () {}); var myClass = new MyClass (); myclass.dowork (); // juzga si MockXHR llama global.servicator = OldServicelocator; // Si olvidas este paso, es fácil causar cosas tristes.4) Pasar en dependencias
Finalmente, se pueden pasar recursos de dependencia.
function myClass (xhr) {this.dowork = function () {xhr ({...}); };}Este es el método preferido, porque el código no necesita prestar atención a dónde proviene XHR, ni le importa quién creó el XHR aprobado. Por lo tanto, el creador de la clase puede codificarse por separado del consumidor de clase, que separa la responsabilidad de la creación de la lógica, que es una visión general de la inyección de dependencia.
Esta clase es fácil de probar, y podemos escribirla así en la prueba:
function xhrmock (args) {…} var myClass = new MyClass (xhrmock); myclass.dowrok (); // hacer algunos juicios ... a través de este código de prueba, podemos darnos cuenta de que no se corrompen las variables globales.Dependencia-inyección (//www.vevb.com/article/91775.htm) incluido con Angular, el código escrito de esta manera facilita el código de prueba. Si queremos escribir un código que sea altamente comprobable, es mejor que lo usemos.
2. Controladores
La lógica hace que cada aplicación sea única, y eso es lo que queremos probar. Si nuestra lógica se mezcla con las operaciones DOM, esto será tan difícil de probar como el siguiente ejemplo:
function PasswordController () {// Obtenga una referencia al objeto DOM var msg = $ ('. Ex1 span'); var entrada = $ ('.. EX1 Entrada'); VAR fuerza; this.grade = function () {msg.removeclass (fuerza); var pwd = input.val (); contraseña.text (pwd); if (pwd.length> 8) {fortaleza = 'fuerte'; } else if (pwd.length> 3) {fortaleza = 'medio'; } else {fortaleza = 'débil'; } msg.addclass (fuerza) .Text (fuerza); }}El código anterior encontrará problemas al probar porque requiere que tengamos el DOM correcto al ejecutar la prueba. El código de prueba será el siguiente:
var input = $ ('<input type = "text"/>'); var span = $ ('<span>'); $ ('cuerpo'). html ('<div>'). find ('div'). append (input) .append (span); var pc = nuevo PasswordController (); input.val ('ABC'); Pc.Grade (); supe (span.text ()). Toqual ('débil'); $ ('cuerpo'). Html ('');En Angular, el controlador separa estrictamente la lógica de operación DOM, que reducirá en gran medida la dificultad de escribir casos de prueba. Eche un vistazo al siguiente ejemplo:
function PasswordCntrl ($ Scope) {$ Scope.password = ''; $ scope.grade = function () {var size = $ scope.password.length; if (size> 8) {$ scope.strength = 'strong'; } else if (size> 3) {$ scope.strength = 'mediano'; } else {$ scope.strength = 'débil'; }};}El código de prueba es sencillo:
var pc = nueva contraseña Controller ($ Scope); PC.Password ('ABC'); Pc.Grade (); WIEP ($ Scope.strength) .toequal ('débil');Vale la pena señalar que el código de prueba no solo es más discontinuo, sino que es más fácil de rastrear. Siempre hemos dicho que los casos de prueba están contando historias, no juzgar otras cosas irrelevantes.
3. Filtros
El filtro (http://docs.angularjs.org/api/ng.$filter) se usa para convertir los datos en un formato fácil de usar. Son importantes porque separan la responsabilidad de convertir formatos de la lógica de la aplicación, simplificando aún más la lógica de la aplicación.
mymodule.filter ('longitud', function () {return function (text) {return (''+(text || '')). longitud;}}); var longitud = $ filtre ('longitud'); expects (longitud (null)). toqual (0); spries (longitud ('ABC')). Toqual (3);4. Directivas
5. Mocks
6. Aislamiento del estado global
7. Forma de prueba preferida
8. JavaScriptTestdriver
9. Jazmín
10. Proyecto de muestra
Continuaremos actualizando artículos relacionados en el futuro. ¡Gracias por su apoyo para este sitio!