Tengo aquí una función que devuelve un color hexadecimal aleatorio
function randomHex() { return `#${Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0")}`; }¿Cómo puedo probarlo con broma? quiero saber si realmente devuelve un hexágono aleatorio o no
tal vez algo como
const { randomHex } = require('../../../'); describe('', () => { it('', () => { const firstRandomColor = randomHex(); const secondRandomColor = randomHex(); const hexRegex = /^#(?:[0-9a-fA-F]{3}){1,2}$/; expect(firstRandomColor).toMatch(hexRegex); expect(secondRandomColor).toMatch(hexRegex); expect(firstRandomColor).not.toBe(secondRandomColor); }) })Para citarme a mí mismo, de esta publicación :
Para que podamos pensar en cómo probarlo, aquí hay una implementación básica de un lanzamiento de moneda:
const flipCoin = () => Math.random() < 0.5 ? "heads" : "tails";Podemos estar bastante seguros de que si llamamos a esta función un gran número de veces obtendremos aproximadamente la mitad de cada resultado:
> Array(10).fill(null).map(() => flipCoin()); [ "tails", "heads", "heads", "tails", "tails", "tails", "heads", "heads", "tails", "tails" ]pero para una llamada determinada no podemos estar seguros de cuál será. Entonces, ¿cómo podemos escribir una prueba para eso? Podríamos volver a buscar el patrón de fachada, extraer
const random = () => Math.random()y reemplazarlo con un doble de prueba. Esto funcionaría bien, pero estaría muy unido a la implementación:describe("flipCoin", () => { it("returns 'heads' when the random number is less than 0.5", () => { random.mockReturnValue = 0.3; expect(flipCoin()).toEqual("heads"); }); });Una alternativa es escribir pruebas basadas en las propiedades de la implementación que queremos. Por ejemplo, aunque no conocemos los valores específicos, sí sabemos:
- Siempre debe dar uno de los resultados esperados; y
- No siempre debería dar el mismo resultado (de lo contrario
() => "heads"sería una implementación válida).
En este caso, una prueba basada en propiedades podría verse así:
describe("randomHex", () => { it("always returns a colour", () => { const colours = Array(100).fill(null).map(() => randomHex()); colours.every((colour) => expect(colour).toMatch(/^#[\da-f]{6}$/)); }); it("doesn't always return the same colour", () => { const colours = Array(100).fill(null).map(() => randomHex()); expect(new Set(colours).size).toBeGreaterThan(1); // or a higher number, but eg `.toEqual(colours.length)` can fail due to collisions }); });