Jest: Prueba si es objeto, matriz o cadena.

Creado en 3 may. 2017  ·  29Comentarios  ·  Fuente: facebook/jest

¿Hay alguna forma de comprobar si un componente es un objeto, una matriz o una cadena? Esto sería similar a chai 'should.be.a' Ej .: validationResult.SSN [0] .should.be.a ('cadena').

Comentario más útil

Una simple extensión toBeType para quienes la deseen

expect.extend({
    toBeType(received, argument) {
        const initialType = typeof received;
        const type = initialType === "object" ? Array.isArray(received) ? "array" : initialType : initialType;
        return type === argument ? {
            message: () => `expected ${received} to be type ${argument}`,
            pass: true
        } : {
            message: () => `expected ${received} to be type ${argument}`,
            pass: false
        };
    }
});

describe("testing extended expect", () => {
    it("tests normal types correctly", () => {
        expect("").toBeType("string");
        expect({}).toBeType("object");
        expect(1).toBeType("number");
    });
    it("tests array types correctly", () => {
        expect([]).toBeType("array");
    });
    it("works with promises", () => {
        expect(Promise.resolve([])).resolves.toBeType("array");
    });
});

Bastante simple de implementar. Realmente debería estar en el núcleo tbh.

Nota: si está poniendo esa extensión en sus archivos de configuración, entonces la quiere en setupTestFrameworkScriptFile NOT setupFiles (ya que la extensión está disponible solo en el primero)

Todos 29 comentarios

No, no lo hay. Encontrará la lista de todos los emparejadores disponibles aquí: https://facebook.github.io/jest/docs/en/expect.html

También puede usar JavaScript simple o una biblioteca auxiliar como lodash para eso:

test('name', () => {
  // array
  expect(Array.isArray(['value'])).toBe(true);
  // string
  expect(typeof 'value').toBe('string');
  // object
  expect({value: 'value'}).toBeTruthy();
  expect(typeof {value: 'value'}).toBe('object');
})

Punto menor: esto no ayuda con los resultados prometedores.

expect(somePromise).resolves.toBe(...) en este punto no hay forma de verificar el tipo. Si no le importa cuál es el contenido , sino que es una cadena. Esperaba que expects.stringContaining("") fuera una solución alternativa, pero eso tampoco funciona.

@abritinthebay Estoy exactamente en esa situación y este es el primer resultado en Google, ¿tal vez esto debería reabrirse?

Ciertamente debería pensarse un poco más. Mi solución fue agregar a la cadena para que haga la parte typeof . p.ej:

expect(somePromise.then(data => typeof data)).resolves.toBe("object");

funciona, pero no está exactamente limpio.

@thymikee La comprobación de tipos de cosas es un caso de uso bastante común (universal) que en realidad no hay ninguna excusa para un marco de prueba que carece de ellos. Sus alternativas son inaceptables ya que perdemos todo contexto de lo que estamos probando.

Este expect(Array.isArray(['value'])).toBe(false); falla con

expect(received).toBe(expected)
    Expected value to be (using ===):
      false
    Received:
      true. 

Entonces, o recibimos mensajes de afirmación terribles o tenemos que extender Jest para respaldar este tipo de comprobaciones. ¿No tiene más sentido para los mantenedores de Jest hacer esto una vez en lugar de que cada persona que usa requiera estas funciones para implementarlas por su cuenta?

Cree sus propios comparadores con expect.extend y publíquelos como un módulo npm. Si se vuelve popular, podemos fusionarlo con el núcleo de Jest eventualmente;)

Una simple extensión toBeType para quienes la deseen

expect.extend({
    toBeType(received, argument) {
        const initialType = typeof received;
        const type = initialType === "object" ? Array.isArray(received) ? "array" : initialType : initialType;
        return type === argument ? {
            message: () => `expected ${received} to be type ${argument}`,
            pass: true
        } : {
            message: () => `expected ${received} to be type ${argument}`,
            pass: false
        };
    }
});

describe("testing extended expect", () => {
    it("tests normal types correctly", () => {
        expect("").toBeType("string");
        expect({}).toBeType("object");
        expect(1).toBeType("number");
    });
    it("tests array types correctly", () => {
        expect([]).toBeType("array");
    });
    it("works with promises", () => {
        expect(Promise.resolve([])).resolves.toBeType("array");
    });
});

Bastante simple de implementar. Realmente debería estar en el núcleo tbh.

Nota: si está poniendo esa extensión en sus archivos de configuración, entonces la quiere en setupTestFrameworkScriptFile NOT setupFiles (ya que la extensión está disponible solo en el primero)

Gracias @abritinthebay

Así que lo envolví en un módulo npm si la gente lo quería:

https://www.npmjs.com/package/jest-tobetype

describe("assertion framework", ()=> {
 it("should check primitive types", () => {
   expect(expect.toBeA).toBeA("function")
  })
})

Fallido: espera (...). ToBeA no es una funciónTypeError: espera (...). ToBeA no es una función

https://github.com/jest-community/jest-extended tiene todos los comparadores de tipos que podrías desear (creo).

He estado usando toBeInstanceOf en mis pruebas:

expect($wrapper.vm.countries).toBeInstanceOf(Array);

Cree sus propios comparadores con wait.extend luego y publíquelos como un módulo npm. Si se vuelve popular, podemos fusionarlo con el núcleo de Jest eventualmente;)

Sí, y podría escribir su propio marco de broma, mientras lo hace.

Esta podría encabezar las peores respuestas que puede obtener en GitHub.

Entonces @abritinthebay hizo exactamente lo que solicitó @thymikee (que fue mucho más que la solicitud de extracción estándar).

Ahora que esa alma valiente hizo todo el trabajo, ¿cuándo podremos el resto de nosotros finalmente obtener este comparador (sin tener que instalar otra biblioteca)? ¿Los mantenedores siguen impulsando la idea de que esto no pertenece a Jest, o simplemente se les escapó del radar?

Somos bastante estrictos con lo que lo convierte en núcleo y normalmente no agregamos emparejadores de azúcar. Jest core es una arquitectura bastante grande y cada comparador que agregamos aumenta el costo de mantenimiento

Para el azúcar, generalmente recomendamos https://github.com/jest-community/jest-extended

El azúcar de un hombre es la característica realmente útil y lógica de otro hombre (o en este caso, al menos de otras siete personas) que pertenece a la biblioteca central.

Obviamente, como mantenedor, su voto supera a todos los nuestros, y tiene todo tipo de preocupaciones que nosotros no, así que lo respeto plenamente. Pero simplemente le pediría que mire por qué todos aquí consideran que esta característica pertenece a la biblioteca central (con tanta fuerza que una persona pasó por varios aros para escribir el código por usted). Hay una necesidad aquí, y si la ignora, los usuarios de la

.to.be.an.instanceOf no va a ser la cantidad de usuarios que piensan verificar los tipos, por lo que para esos usuarios, incluso si lo ve como azúcar, les está negando efectivamente la capacidad de verificar tipos en Jest sin una biblioteca adicional.

Sí, te escucho. Para ser claros, por "azúcar" me refiero a la sintaxis que está diseñada para hacer las cosas más fáciles de leer o expresar . El azúcar, por definición, es una variación de una característica que ya existe.

En este caso, tenemos:

// Supported
expect(typeof foo).toBe('string');

// Proposed Sugar
expect(foo).toBeType('string');

Por lo tanto, no es que no admitamos tipos de verificación. Hacemos. Apoyamos la primera opción. Esta opción utiliza el comparador principal toBe que hemos pasado mucho tiempo solucionando los errores y ajustando el mensaje para que los usuarios tengan una buena experiencia

Hay casi 60 emparejamientos en broma extendida y muchos de ellos son azúcar pura. Para cualquiera de esos comparadores, probablemente podría encontrar al menos otras 7 personas que los encuentren realmente útiles, por lo que si esa fuera la heurística que usamos para agregar al núcleo, probablemente pasaríamos todo nuestro tiempo simplemente manteniendo los comparadores

Para ser completamente justos, la mayoría de los emparejadores son "azúcar" en algún nivel. Quiero decir que toBeGreaterThanOrEqual es solo azúcar por expect(foo >= bar).toBe(true);

Los comparadores son en realidad _ casi todos_ azúcar alrededor de declaraciones booleanas;)

(Digo esto no para cavar, solo para señalar que es ... una línea muy borrosa)

Como sugirió abritinthebay, no se trata realmente de azúcar, se trata de azúcar "necesaria" e "innecesaria" (para la biblioteca central). Hay un montón de personas en este hilo que dicen "oye, poder comprobar todos los tipos es algo que debería estar en el núcleo de una biblioteca de pruebas" (es decir, es necesario).

Escúchanos o no, de nuevo, como mantenedor, tienes muchas otras preocupaciones. Pero no creo que la respuesta correcta sea decir "lo tuyo es azúcar inherentemente innecesario" (ese soy yo tratando de parafrasearte, no tratando de ponerte palabras en la boca) cuando no es inherente: es 100% tu decisión si Jest Puede marcar todos los tipos o no fuera de la caja.

¿qué pasa, no es tan difícil: P?

expect(Array.isArray(['your', 'array'])).toBe(true);

expect(typeof something === "object").toBe(true); 
// - or -
expect(something instanceof Object).toBe(true);

expect(typeof something === "string").toBe(true); 

@nahumzs Si bien funciona, el problema es que en la salida de su prueba cuando falla, dirá 'se esperaba que falso fuera cierto', lo cual no es muy útil;)

Creo que este es el camino a seguir :)

describe('type check', () => {
    test('should be type string', () => {
        expect(typeof '').toBe('string')
    })

    test('should be type number', () => {
        expect(typeof 10).toBe('number')
    })

    test('should be type boolean', () => {
        expect(typeof true).toBe('boolean')
    })

    test('should be type undefined', () => {
        expect(typeof undefined).toBe('undefined')
    })

    test('should be type object', () => {
        expect(typeof { foo: 'bar' }).toBe('object')
    })

    test('should be type function', () => {
        expect(typeof function() {}).toBe('function')
    })

    test('should be type null', () => {
        expect(typeof null).toBe('object')
    })
})

Refactoré la implementación proporcionada por @abritinthebay. Me parece un poco cómodo trabajar con él.

`` `javascript
esperar.extender ({
/ ** @param { } recibido
* @param {cadena | cadena []} arg
* @return {{pass: boolean, message: (function (): string)}}
* /
toBeType (recibido, arg) {
const isCorrectType = arg => {
constivedType = tipo de recibido;

        const checkForSingle = arg => {
            const type = receivedType === 'object'
                ? Array.isArray(received)
                    ? 'array'
                    : receivedType
                : receivedType;

            return type === arg;
        };

        const checkForArr = arg => {
            const reducer = (prev, curr) => prev || isCorrectType(curr).isCorrect;

            return arg.reduce(reducer, false);
        };

        return {
            receivedType,
            isCorrect: Array.isArray(arg)
                ? checkForArr(arg)
                : checkForSingle(arg)
        };
    };

    const {isCorrect, receivedType} = isCorrectType(arg);

    return {
        pass: isCorrect,
        message: () => {
            const toBe = Array.isArray(arg)
                ? arg.join(`' or '`)
                : arg;

            return `Expected '${received}' of '${receivedType}' type to be of '${toBe}' type(s)`;
        }
    };
}

});

Debería consultar mi módulo (vinculado arriba). Hace un poco más que eso. Pero si eso funciona para usted: ¡utilícelo!

Creo que este es el camino a seguir :)

describe('type check', () => {
    test('should be type string', () => {
        expect(typeof '').toBe('string')
    })

    test('should be type number', () => {
        expect(typeof 10).toBe('number')
    })

    test('should be type boolean', () => {
        expect(typeof true).toBe('boolean')
    })

    test('should be type undefined', () => {
        expect(typeof undefined).toBe('undefined')
    })

    test('should be type object', () => {
        expect(typeof { foo: 'bar' }).toBe('object')
    })

    test('should be type function', () => {
        expect(typeof function() {}).toBe('function')
    })

    test('should be type null', () => {
        expect(typeof null).toBe('object')
    })
})

Funciona de maravilla, además de ser más legible y fácil de mantener para el futuro.

Creo que este es el camino a seguir :)

describe('type check', () => {
    test('should be type string', () => {
        expect(typeof '').toBe('string')
    })

    test('should be type number', () => {
        expect(typeof 10).toBe('number')
    })

    test('should be type boolean', () => {
        expect(typeof true).toBe('boolean')
    })

    test('should be type undefined', () => {
        expect(typeof undefined).toBe('undefined')
    })

    test('should be type object', () => {
        expect(typeof { foo: 'bar' }).toBe('object')
    })

    test('should be type function', () => {
        expect(typeof function() {}).toBe('function')
    })

    test('should be type null', () => {
        expect(typeof null).toBe('object')
    })
})
    test('should be type object', () => {
        expect(typeof { foo: 'bar' }).toBe('object')
        // passes
        expect(typeof ['foo', 'bar']).toBe('object')
        // passes
        expect(typeof null).toBe('object')
    })

😞

Es por eso que sugiero mi complemento anterior: se encarga de esto.

InstanceOf es un poco mejor pero propenso a problemas similares.

Enlace a él:

https://www.npmjs.com/package/jest-tobetype

gracias por la solución @abritinthebay

Otra solución:

expect('example').toEqual(expect.any(String));
expect(123).toEqual(expect.any(String));

El segundo fallaría con:

    Expected: Any<String>
    Received: 123
¿Fue útil esta página
0 / 5 - 0 calificaciones