API
Esta página foi traduzida por PageTurner AI (beta). Não é oficialmente endossada pelo projeto. Encontrou um erro? Reportar problema →
Como foi inspirado na preact-testing-library, você pode consultar a página dela para mais informações.
Existem várias diferenças importantes para se atentar.
render
A função render recebe uma função que retorna um Componente Solid, em vez de simplesmente o componente em si.
const results = render(() => <YourComponent />, options)
O Solid.js não faz re-renderização, ele apenas executa efeitos colaterais acionados por estado reativo que alteram o DOM. Portanto, não existe um método rerender. Você pode usar sinais globais para manipular seu componente de teste de forma que ele seja atualizado.
Além da API original, a função render desta biblioteca de testes suporta uma opção conveniente location que configurará um roteador em memória apontando para o local especificado. Como essa configuração não é síncrona, você precisa primeiro usar consultas assíncronas (findBy) após empregá-la:
it('uses params', async () => {
const App = () => (
<>
<Route path="/ids/:id" component={() => <p>Id: {useParams()?.id}</p>} />
<Route path="/" component={() => <p>Start</p>} />
</>
)
const {findByText} = render(() => <App />, {location: 'ids/1234'})
expect(await findByText('Id: 1234')).not.toBeFalsy()
})
Ela utiliza @solidjs/router, então se você quiser usar um roteador diferente, deve considerar a opção wrapper. Se tentar usar isso sem ter o pacote instalado, receberá uma mensagem de erro.
renderHook
O estado reativo externo do Solid.js não requer nenhum elemento DOM para ser executado, então nossa chamada renderHook para testar hooks no contexto de um componente (se seu hook não requer o contexto de um componente, createRoot deve ser suficiente para testar o comportamento reativo; por conveniência, também temos createEffect, descrito na seção Async methods) não possui container, baseElement ou queries em suas opções ou valor de retorno. Em vez disso, ele tem um owner para ser usado com runWithOwner se necessário. Ele também expõe uma função cleanup, embora esta já seja chamada automaticamente após o teste terminar.
function renderHook<Args extends any[], Result>(
hook: (...args: Args) => Result,
options: {
initialProps?: Args,
wrapper?: Component<{ children: JSX.Element }>
}
) => {
result: Result;
owner: Owner | null;
cleanup: () => void;
}
Isso pode ser usado para testar facilmente um hook / primitiva:
const {result} = renderHook(createResult)
expect(result).toBe(true)
Se estiver usando um wrapper com renderHook, certifique-se de que ele sempre retorne props.children - especialmente se estiver usando um contexto com código assíncrono junto com <Show>, porque isso é necessário para obter o valor do hook e ele é obtido apenas uma vez de forma síncrona; caso contrário, você só obterá undefined e ficará se perguntando por que isso está acontecendo.
renderDirective
O Solid.js suporta diretivas personalizadas, que são um padrão conveniente para vincular comportamentos personalizados a elementos. Por isso, também temos uma chamada renderDirective, que estende renderHook para receber uma diretiva como primeiro argumento, aceitar um initialValue para o argumento e um targetElement (string, HTMLElement ou função que retorna um HTMLElement) nas options e também retorna arg e setArg para ler e manipular o argumento da diretiva.
function renderDirective<
Arg extends any,
Elem extends HTMLElement
>(
directive: (ref: Elem, arg: Accessor<Arg>) => void,
options?: {
...renderOptions,
initialValue: Arg,
targetElement:
| Lowercase<Elem['nodeName']>
| Elem
| (() => Elem)
}
): Result & { arg: Accessor<Arg>, setArg: Setter<Arg> };
Isso permite testes de diretivas muito eficazes e concisos:
const {asFragment, setArg} = renderDirective(myDirective)
expect(asFragment()).toBe('<div data-directive="works"></div>')
setArg('perfect')
expect(asFragment()).toBe('<div data-directive="perfect"></div>')
Async methods
As alterações reativas do Solid.js são praticamente instantâneas, então raramente há necessidade de usar waitFor(…), await findByRole(…) e outras consultas assíncronas para testar o resultado renderizado, exceto para transições, suspense, recursos e navegação do roteador.
O Solid.js gerencia efeitos colaterais com diferentes variantes de createEffect. Embora você possa usar waitFor para testar efeitos assíncronos, ele usa polling em vez de permitir que a reatividade do Solid dispare o próximo passo. Para simplificar o teste desses efeitos assíncronos, temos um auxiliar testEffect que complementa os hooks para diretivas e hooks:
testEffect(fn: (done: (result: T) => void) => void, owner?: Owner): Promise<T>
// use it like this:
test("testEffect allows testing an effect asynchronously", () => {
const [value, setValue] = createSignal(0);
return testEffect(done => createEffect((run: number = 0) => {
if (run === 0) {
expect(value()).toBe(0);
setValue(1);
} else if (run === 1) {
expect(value()).toBe(1);
done();
}
return run + 1;
}));
});
Ele permite executar o efeito dentro de um owner definido que é recebido como segundo argumento opcional. Isso pode ser útil em combinação com o renderHook, que fornece um campo owner em seu resultado. O valor retornado é uma Promise com o valor passado para o callback done(). Você pode aguardar o resultado para fazer mais asserções ou retorná-lo ao seu test runner.
Problemas conhecidos
Se você estiver usando vitest, os testes podem falhar porque os pacotes solid-js e @solidjs/router (se usado) precisam ser carregados apenas uma vez, mas podem ser carregados tanto pelo servidor interno do vite quanto pelo node. Erros típicos incluem dispose supostamente sendo undefined ou falha ao carregar o roteador.
A partir da versão 2.8.2, nosso plugin do vite ganhou capacidade para configurar tudo para testes, então você só precisará de configuração adicional para globals, coverage, etc.