Sinon: Documente como configurar o Node para permitir o stub de módulos EcmaScript

Criado em 8 jun. 2018  ·  17Comentários  ·  Fonte: sinonjs/sinon

Módulos EcmaScript que são executados em um ambiente que os suporta (significando que não foram transpilados usando Babel para ES5) e exportam uma função default de algum tipo não podem ser fragmentados, pois os namespaces ES são imutáveis ​​de acordo com as especificações. Não há nada que a Sinon possa fazer sobre isso, então lançamos um erro explicitamente quando você tenta fazer isso: 'ES Modules cannot be stubbed' .

Mas @jdalton fez esm , um runtime loader para Node que permite carregar módulos EcmaScript ( *.mjs ), e para permitir stub usando Sinon e similares, ele adicionou o mutableNamespace opção para esm .

Deve haver um artigo em nossa seção Como fazer que mostra como configurar npm para executar o nó usando esm e a opção, junto com um script de teste.

Referências:

Documentation ES2015+ Help wanted good first issue hacktoberfest pinned

Comentários muito úteis

@giltayar Parabéns pela implementação do suporte ESM! Ótimo artigo, aliás. Sempre dissemos que o stub do módulo ES não é possível em tempos de execução ESM em conformidade, mas também dissemos (como acima) que isso deve ser tratado no nível de vinculação, usando algo como proxyquire, rewire ou ... Quibble, que é onde você adicionou o suporte :)

Em meu projeto de trabalho, usamos proxyquire para remover as dependências dos Módulos ES:

proxyquire('./mylib.mjs', {doSomething: () => 'done'})

Seria bastante equivalente no Quibble (usado por TestDouble), onde o artigo tem um exemplo como este, mas o Quibble não suporta stubs parciais, então é um pouco diferente no que eles fazem.

await quibble.esm('./mylib.mjs', {doSomething: () => 'done'}, 'yabadabadoing') // not sure what this third param does ...

Portanto, de acordo com o que foi dito anteriormente, a Sinon nunca adicionará explicitamente suporte para simulação de Módulos ES, pois é melhor deixar para Quibble, Proxyquire, Rewire, NormalModuleReplacementPlugin (webpack) e todas as outras maneiras de fazer isso que seja 100% ambiental dependente.

Todos 17 comentários

Tenho pensado em escrever exatamente isso :)

O "problema" é que há uma infinidade de maneiras diferentes de esm podem ser usados, mas devemos pelo menos cobrir o caso mais comum, que eu suporia através do sinalizador require para o node processo. Comecei a descobrir como usar o arquivo de configuração aqui , mas parece que também é possível fornecer uma string json como uma variável de ambiente (além de um hash de opções se estiver usando código).

Olá @ fatso83!

A opção cjs.mutableNamespace é habilitada por padrão, então não há configuração necessária. O stub irá funcionar com .js mas não com .mjs _ ( .mjs arquivos estão bloqueados, portanto, não há esm options) _.

@jdalton Obrigado por nos informar sobre a distinção js vs mjs . Isso explica por que esse cara não conseguiu fazer funcionar.

cc @ jim-king-2000

Eu gostaria de escrever um teste de unidade com o custo mínimo. Se a solução fosse tão complicada, prefiro abandonar o teste de unidade com simulação. Afinal, o teste simulado não é o método obrigatório para construir um sistema online robusto. Mas, como último recurso, é possível que o sinon envolva o "proxyrequire" (ou algo parecido) para mim?

@ jim-king-2000 Isso está fora do escopo. Você optou explicitamente por usar um sistema de módulo cujas exportações devem ser imutáveis. Infelizmente, esse é um custo que você terá de suportar. Envolver carregadores de módulo, fazendo-os funcionar em todos os tipos de cenários (Node, navegador, com / sem transpiladores, etc) é muito caro e realmente não tem nada a ver com os objetivos declarados deste projeto .

Eu não entendo muito bem a relevância do sinon e do sistema de módulos (desculpe). O que eu preciso é de uma estrutura de teste de unidade simulada js / node (ou biblioteca, como a contraparte java, mockito) sem babel. Então, isso existe?

Resumindo, para o seu nicho específico: não atualmente: sob:
Em geral: sim, existem maneiras de conseguir isso para quase qualquer combinação de frameworks e tempos de execução.

Em termos de Java, é como implementar seu sistema inteiro usando métodos Java static e, em seguida, tentar simular as classes usando Mockito. Isso não pode ser feito.

Dito isso, tudo que você precisa para fazer as coisas funcionarem é renomear seus *.mjs arquivos para *.js . Este parece ser um meio-termo pragmático, pois você ganhará testabilidade sem quaisquer desvantagens conhecidas.

Para simulação de função estática do Java, usamos powermock. Mas posso não entender totalmente a comparação. Aliás, não gosto de java, sua evolução é muito lenta. Agora ele ainda NÃO suporta assíncrono / espera.

Eu uso * .mjs em todos os lugares, todos os códigos-fonte são arquivos mjs. Além do mais, isso significa que eu tenho que recorrer ao babel novamente (introduzindo trabalho de desenvolvimento / tempo de execução extra e pilha de chamadas confusa). Tudo bem se eu pudesse apenas alterar os arquivos de teste de volta para * .js.

Vou abandonar ut com mock (outros testes estão intactos) até encontrar outras formas de baixo custo.

@ fatso83 Obrigado pela ajuda o tempo todo.

Alguém tentou reclamar ? 🤔

Para sua informação, implementei o suporte a Node.js ESM em "testdouble.js", que é uma biblioteca de simulação. É possível. Escrevi sobre a implementação nesta postagem do blog:

https://dev.to/giltayar/mock-all-you-want-supporting-es-modules-in-the-testdouble-js-mocking-library-3gh1

Ficaria feliz em ajudar aqui se alguém quiser assumir ..

@giltayar Parabéns pela implementação do suporte ESM! Ótimo artigo, aliás. Sempre dissemos que o stub do módulo ES não é possível em tempos de execução ESM em conformidade, mas também dissemos (como acima) que isso deve ser tratado no nível de vinculação, usando algo como proxyquire, rewire ou ... Quibble, que é onde você adicionou o suporte :)

Em meu projeto de trabalho, usamos proxyquire para remover as dependências dos Módulos ES:

proxyquire('./mylib.mjs', {doSomething: () => 'done'})

Seria bastante equivalente no Quibble (usado por TestDouble), onde o artigo tem um exemplo como este, mas o Quibble não suporta stubs parciais, então é um pouco diferente no que eles fazem.

await quibble.esm('./mylib.mjs', {doSomething: () => 'done'}, 'yabadabadoing') // not sure what this third param does ...

Portanto, de acordo com o que foi dito anteriormente, a Sinon nunca adicionará explicitamente suporte para simulação de Módulos ES, pois é melhor deixar para Quibble, Proxyquire, Rewire, NormalModuleReplacementPlugin (webpack) e todas as outras maneiras de fazer isso que seja 100% ambiental dependente.

@ fatso83 Se eu puder perguntar por que isso é tão convencido de "nunca adicionar suporte explicitamente"? Eu li isso várias vezes aqui nos últimos dias enquanto procurava desesperadamente por uma solução para simular meu código do módulo ES6.

Nenhuma solução documentada em Jest, nenhuma está aqui. Quase desisti até encontrar o artigo da @giltayar. Que alívio. Eu tenho algo funcionando com o quibble até que percebi que posso apenas usar testdouble.js.

Já é difícil o suficiente que em JavaScript cada pacote tenha seu próprio estilo de documentação e na maioria das vezes nenhum documento de API real, mas também ter que descobrir como funcionam as bibliotecas de teste, bibliotecas de simulação funcionam e carregadores de módulo para bibliotecas de simulação funcionam é demais .

Eu concordo totalmente se você diz que se concentra no Sinon como ele é, enquanto outros podem se concentrar em conectar esses pacotes para o programador do "usuário final". Eu só quero mostrar que há uma dor real para programadores como eu e tenho certeza que muitos ficariam felizes se o processo fosse simplificado, especialmente se muitos migrarem para módulos ES nos próximos anos.

Não tenho um conhecimento técnico tão profundo, apenas pensei que algum feedback da minha experiência poderia ser útil

@ fatso83 Se eu puder perguntar por que isso é tão convencido de "nunca adicionar suporte explicitamente"?

Deixe-me reiterar: é a opinião dos mantenedores do Sinon que lidar com importações simuladas está fora do escopo do Sinon e é melhor abordado por bibliotecas especializadas.

Geralmente, não faz sentido fazer uma biblioteca que tenta fazer tudo, em cada tempo de execução. Projetos de código aberto nem mesmo maiores e bem financiados tentam fazer isso.

Nenhuma solução documentada em Jest, nenhuma está aqui. Quase desisti até encontrar o artigo da @giltayar. Que alívio. Eu tenho algo funcionando com o quibble até que percebi que posso apenas usar testdouble.js.

Bibliotecas diferentes fazem escolhas diferentes.

Os mantenedores do testdouble.js fazem suas próprias escolhas. Eles decidiram publicar sofismas e integrá-los em sua biblioteca. Bom para eles. Se você gosta da solução deles, use-a por suposto. Não temos nada além de amor e respeito por @searls e os mantenedores de testdouble.js.

Já é difícil o suficiente que em JavaScript cada pacote tenha seu próprio estilo de documentação e na maioria das vezes nenhum documento de API real, mas também ter que descobrir como funcionam as bibliotecas de teste, bibliotecas de simulação funcionam e carregadores de módulo para bibliotecas de simulação funcionam é demais .

Eu concordo totalmente se você diz que se concentra no Sinon como ele é, enquanto outros podem se concentrar em conectar esses pacotes para o programador do "usuário final". Eu só quero mostrar que há uma dor real para programadores como eu e tenho certeza que muitos ficariam felizes se o processo fosse simplificado, especialmente se muitos migrarem para módulos ES nos próximos anos.

Não estamos aqui para resolver todos os problemas do ecossistema JavaScript.

Por mais de uma década, vários mantenedores forneceram a família de bibliotecas Sinon gratuitamente. Praticamente todo o trabalho que foi feito para manter essas bibliotecas foi feito como trabalho não remunerado, no tempo livre dos mantenedores. Estamos usando JavaScript profissionalmente e compartilhamos suas frustrações. Mas, nós temos muito tempo para dar de graça.

Não tenho um conhecimento técnico tão profundo, apenas pensei que algum feedback da minha experiência poderia ser útil

O que seria útil seria se você escrevesse uma postagem de blog sobre suas frustrações ao simular dependências, até encontrar uma solução que funcionasse bem para você e como você usou testdouble.js com grande sucesso com sua maneira particular de carregar JavaScript.

Se for uma postagem de blog sólida, ficarei feliz em promovê-la em sinonjs.org .

@mroderick Acho que deveria primeiro ter

Não estamos aqui para resolver todos os problemas do ecossistema JavaScript.

Definitivamente não, isso apenas para mostrar que pode haver uma necessidade maior de ajuda do que com outras línguas (apenas meu palpite).

lidar com importações simuladas está fora do escopo da Sinon e é melhor abordado por bibliotecas especializadas.

É justo, como eu disse, posso entender isso e provavelmente você tem uma compreensão muito mais profunda do esforço envolvido na implementação desses recursos. Além disso, a API do carregador ainda é experimental.

Atualmente, estou trabalhando em uma pequena ferramenta CLI que pretendo lançar como código aberto assim que houver uma versão funcional. Se isso for feito, considero a possibilidade de escrever um post no blog sobre isso. Ainda tentarei o Sinon com proxyquire antes, porque li muitas coisas boas sobre o Sinon.

Ainda tentarei o Sinon com proxyquire antes, porque li muitas coisas boas sobre o Sinon.

Temos um guia sobre como fazer isso: https://sinonjs.org/how-to/link-seams-commonjs/

Se você achar que o guia pode ser melhorado, envie uma solicitação de pull 👍

Esta página foi útil?
0 / 5 - 0 avaliações