Solucionado (ver solução)
Solucionado
(ver solução)
19
respostas

Não estou conseguindo usar o banco de teste

Duvida referente ao curso de Node, aula 07 e tópico 11.

Não consigo utilizar os comandos da aula já que uso Windows mas ao ler esse fórum https://cursos.alura.com.br/forum/topico-aula-07-video-11-comando-node_env-no-windows-36680 do aluno Marcelo pude configurar meu script de test e ele roda quase perfeitamente.

Meu problema é que mesmo setando o valor test ele ainda continua adicionando o novo livro no banco de desenvolvimento.

// package.json

{
  "name": "casadocodigo",
  "version": "1.0.0",
  "description": "site da casa do codigo",
  "main": "app.js",
  "scripts": {
    "start": "set NODE_ENV=test node node_modules/mocha/bin/mocha",
    "test": "mocha"
  },
  "author": "antonio",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.18.2",
    "ejs": "^2.5.7",
    "express": "^4.16.2",
    "express-load": "^1.1.16",
    "express-validator": "^4.3.0",
    "mysql": "^2.15.0"
  },
  "devDependencies": {
    "mocha": "^4.1.0",
    "supertest": "^3.0.0"
  }
}

//connectionFactory

var mysql = require('mysql');
function createDbConnection() {
    if(!process.env.NODE_ENV){
        return mysql.createConnection({
                host : 'localhost',
                user : 'root',
                password : 'root',
                database : 'casadocodigo_nodejs'
        });
    }

    if(process.env.NODE_ENV == 'test'){
        return mysql.createConnection({
            host : 'localhost',
            user : 'root',
            password : 'root',
            database : 'casadocodigo_nodejs_teste'
    });
    }
}

module.exports = function() {
    return createDbConnection;
}

//produtos,js test

it('#cadastro de um novo produto com tudo preenchido', function (done) {
        request.post('/produtos')
            .send({titulo: "titulo", descricao: "novo livro", preco: 20.50})
            .expect(302, done);
    });
19 respostas

Olá, Antônio. Muda seu package.json que ficará assim:

{
  "name": "casadocodigo",
  "version": "1.0.0",
  "description": "site da casa do codigo",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "test": "set NODE_ENV=test node node_modules/mocha/bin/mocha"
  },
  "author": "antonio",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.18.2",
    "ejs": "^2.5.7",
    "express": "^4.16.2",
    "express-load": "^1.1.16",
    "express-validator": "^4.3.0",
    "mysql": "^2.15.0"
  },
  "devDependencies": {
    "mocha": "^4.1.0",
    "supertest": "^3.0.0"
  }
}

Depois você roda no cmd o comando npm test.

Obrigado pela resposta Marco. Fiz as alterações e a saída no cmd foi :

> casadocodigo@1.0.0 test E:\Alura\Carreiras\Desenvolvedor Node.js\Node\JS no Backend\Projetos\casadocodigo
> set NODE_ENV=test node node_modules/mocha/bin/mocha

apenas isso, e verifiquei o banco de teste e nada foi adicionado. Também não foi adicionado no banco de desenvolvimento.

Mal, Antonio.

Você tem que colocar depois do .../bin/mocha o caminho para o seu arquivo de teste. Não deu erro, mas foi por causa disso que não rodou nenhum dos seus testes.

Se você quiser que rode todos os teste que estão dentro de uma pasta você pode trocar a linha de teste do seu package.json e deixar da seguinte forma:

"test": "set NODE_ENV=test node node_modules/mocha/bin/mocha --recursive nomeDaSuaPasta"

Certo Marco. Fiz a devida alteração com o seguinte código já que a pasta de test está no mesmo nível do package.json

"test": "set NODE_ENV=test node node_modules/mocha/bin/mocha --recursive ./test"

A saída no cmd continua sendo a mesma de antes porém com "--recursive ./test"

Antônio. Por favor, tentar executar o comando abaixo direto pelo terminal:

set NODE_ENV=test node node_modules/mocha/bin/mocha --recursive ./test/nomeDeUmArquivoSeuDeTeste.js

Se não funcionar, tem algo bem estranho no mocha. Depois me avise qual será o retorno?

Ola pessoal, desculpe me intrometer, mas só para lembrar que este comando será diferente dependendo do sistema operacional, pois estamos configurando uma variável de ambiente. Se não me engano no vídeo o instrutor passa os comandos para Mac. Caso estiver usando Windows o comando ficará assim:

set "NODE_ENV=test"&&node node_modules/mocha/bin/mocha

Abraço.

Bom dia!

Fiz como Daniel falou. Separei os dois comandos com "&&" e o test rodou porem deu um erro que nao entendi porque aconteceu. Nao mudei o codigo e ta saindo esse resultado:

ProdutosController
TypeError: Cannot read property 'query' of undefined
    at ProdutoBanco.lista (E:\Alura\Carreiras\Desenvolvedor Node.js\Node\JS no Backend\Projetos\casadocodigo\app\infra\ProdutoDAO.js:6:19)
    at E:\Alura\Carreiras\Desenvolvedor Node.js\Node\JS no Backend\Projetos\casadocodigo\app\routes\produtos.js:8:14
    at Layer.handle [as handle_request] (E:\Alura\Carreiras\Desenvolvedor Node.js\Node\JS no Backend\Projetos\casadocodigo\node_modules\express\lib\router\layer.js:95:5)
    at next (E:\Alura\Carreiras\Desenvolvedor Node.js\Node\JS no Backend\Projetos\casadocodigo\node_modules\express\lib\router\route.js:137:13)    at Route.dispatch (E:\Alura\Carreiras\Desenvolvedor Node.js\Node\JS no Backend\Projetos\casadocodigo\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (E:\Alura\Carreiras\Desenvolvedor Node.js\Node\JS no Backend\Projetos\casadocodigo\node_modules\express\lib\router\layer.js:95:5)
    at E:\Alura\Carreiras\Desenvolvedor Node.js\Node\JS no Backend\Projetos\casadocodigo\node_modules\express\lib\router\index.js:281:22
    at Function.process_params (E:\Alura\Carreiras\Desenvolvedor Node.js\Node\JS no Backend\Projetos\casadocodigo\node_modules\express\lib\router\index.js:335:12)

Comentei meu codigo para testar o banco de teste e funcionou

function createDbConnection() {
    /* if(!process.env.NODE_ENV){
        return mysql.createConnection({
                host : 'localhost',
                user : 'root',
                password : 'root',
                database : 'casadocodigo_nodejs'
        });
    }

    if(process.env.NODE_ENV == 'test'){ */
        return mysql.createConnection({
            host : 'localhost',
            user : 'root',
            password : 'root',
            database : 'casadocodigo_nodejs_teste'
    });
    //}
}

Não sei se isso ajuda a entender o real problema mas meu banco de teste funciona.

Bom dia Antônio.

Pra podermos te ajudar, coloca aqui o código dos seguintes fontes:

app\infra\ProdutoDAO.js
app\routes\produtos.js

Pra complementar o erro:

1) ProdutosController
       #listagem json:
     Error: expected "Content-Type" matching /json/, got "text/html; charset=utf-8"
      at Test._assertHeader (node_modules\supertest\lib\test.js:243:14)
      at Test._assertFunction (node_modules\supertest\lib\test.js:281:11)
      at Test.assert (node_modules\supertest\lib\test.js:171:18)
      at Server.assert (node_modules\supertest\lib\test.js:131:12)
      at emitCloseNT (net.js:1689:8)
      at process._tickCallback (internal/process/next_tick.js:152:19)

  2) ProdutosController
       #listagem html:
     Error: expected 200 "OK", got 500 "Internal Server Error"
      at Test._assertStatus (node_modules\supertest\lib\test.js:266:12)
      at Test._assertFunction (node_modules\supertest\lib\test.js:281:11)
      at Test.assert (node_modules\supertest\lib\test.js:171:18)
      at Server.assert (node_modules\supertest\lib\test.js:131:12)
      at emitCloseNT (net.js:1689:8)
      at process._tickCallback (internal/process/next_tick.js:152:19)

  3) ProdutosController
       #cadastro de um novo produto com tudo preenchido:
     Error: expected 302 "Found", got 500 "Internal Server Error"
      at Test._assertStatus (node_modules\supertest\lib\test.js:266:12)
      at Test._assertFunction (node_modules\supertest\lib\test.js:281:11)
      at Test.assert (node_modules\supertest\lib\test.js:171:18)
      at Server.assert (node_modules\supertest\lib\test.js:131:12)
      at emitCloseNT (net.js:1689:8)
      at process._tickCallback (internal/process/next_tick.js:152:19)

// connectionFactory.js

var mysql = require('mysql');
function createDbConnection() {
    if(!process.env.NODE_ENV){
        return mysql.createConnection({
                host : 'localhost',
                user : 'root',
                password : 'root',
                database : 'casadocodigo_nodejs'
        });
    }

    if(process.env.NODE_ENV == 'test'){
        return mysql.createConnection({
            host : 'localhost',
            user : 'root',
            password : 'root',
            database : 'casadocodigo_nodejs_teste'
    });
    }
}

module.exports = function() {
    return createDbConnection;
}

//ProdutoDAO.js

function ProdutoBanco(connection) {
    this._connection = connection;
}

ProdutoBanco.prototype.lista = function (callback) {
    this._connection.query('select * from produtos', callback);
}

ProdutoBanco.prototype.salva = function(produto, callback) {
    console.log("produto :"+produto);
    this._connection.query('insert into produtos set ?', produto, callback);
}

module.exports = function () {
    return ProdutoBanco;
}

Antônio, provavelmente a sua variável de ambiente "NODE_ENV" ainda não está configurada.

Altera o seu arquivo connectionFactory.js para logar no console o conteúdo desta variável, da seguinte forma:

function createDbConnection() {
    console.log("NODE_ENV: " + process.env.NODE_ENV);
    if(!process.env.NODE_ENV){
    ...

Importante: O que você está digitando no cmd para executar os testes?

Se puder coloca o produtos.js aqui, que faltou.

Certo, vamos la: a saida do console foi:

 ProdutosController
NODE_ENV: test

entao ate ai tudo certo.

estou digitando no cmd "npm test" pois configurei o package.json pra isso:

//package.json

{
  "name": "casadocodigo",
  "version": "1.0.0",
  "description": "site da casa do codigo",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "test": "set NODE_ENV=test && node node_modules/mocha/bin/mocha --recursive ./test/produtos.js"
  },
  "author": "antonio",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.18.2",
    "ejs": "^2.5.7",
    "express": "^4.16.2",
    "express-load": "^1.1.16",
    "express-validator": "^4.3.0",
    "mysql": "^2.15.0"
  },
  "devDependencies": {
    "mocha": "^4.1.0",
    "supertest": "^3.0.0"
  }
}

// Produto.js

var express = require('../config/express')();
var request = require('supertest')(express);
describe('ProdutosController', function() {


    it('#listagem json', function (done) {

        request.get('/produtos')
            .set('Accept','application/json')
            .expect('Content-Type',/json/)
            .expect(200, done);

    });

    it('#listagem html', function (done) {

        request.get('/produtos')
            .set('Accept','text/html')
            .expect('Content-Type','text/html; charset=utf-8')
            .expect(200, done);

    });

    it('#cadastro de novo produto com dados invalidos', function(done){
        request.post('/produtos')
            .send({titulo: ""})
            .expect(400, done);
    });

    it('#cadastro de um novo produto com tudo preenchido', function (done) {
        request.post('/produtos')
            .send({titulo: "titulo", descricao: "novo livro", preco: 20.50})
            .expect(302, done);
    });
});

Era esse o arquivo que eu me referia:

app\routes\produtos.js

Certo, ai esta:

// Arquivo de configurações de rotas

module.exports = function (app) {
    app.get('/produtos',function(request, response, next) {
        var connection = app.infra.connectionFactory();
        var produtoDAO = new app.infra.ProdutoDAO(connection);

        produtoDAO.lista(function (erro, results) {
            if(erro){
                return next(erro);
            }
            response.format({
                html: function() {
                    response.render('produtos/lista', {lista:results});
                },
                json: function() {
                    response.json(results);
                }
            });
        });

        connection.end();
    });

    app.get('/produtos/form', function (request, response) {
        response.render('produtos/form', {errosValidacao:{}, produto:{}});
    });

    app.post('/produtos',function(request, response) {
        var produto = request.body;
        validaCampos(request);
        var erros = request.validationErrors();
        if(erros.length > 0) {
            response.format({
                html: function() {
                    response.status(400).render('produtos/form', {errosValidacao:erros, produto:produto});
                },
                json: function() {
                    response.status(400).json(erros);
                }
            });

            return;
        }

        var connection = app.infra.connectionFactory();
        var produtoDAO = new app.infra.ProdutoDAO(connection);

        produtoDAO.salva(produto, function(erro, resultado) {
                response.redirect('produtos');
        });
        connection.end();
    });
}

function validaCampos(request) {
    request.assert('titulo', 'Titulo é obrigatório').notEmpty().trim();
    request.assert('preco', 'Formato inválido').isFloat();
    request.assert('descricao', 'Descrição é obrigatória').notEmpty().trim();
}

Tenta rodar o teu teste exatamente desta forma, diretamente no cmd:

set "NODE_ENV=test"&&node node_modules/mocha/bin/mocha

Se não funcionar, compacta o teu projeto e disponibiliza aqui pra nós (ou coloca no github). Só debugando pra entender melhor.

Bem provável que a connection esta ficando nula pois, por algum motivo, ele não está conseguindo conectar no banco.

Daniel, tirei as aspas duplas e funcionou.

Muito obrigado pela ajuda.

A unica duvida de fato agora é por que que meu "npm test" nao esta funcionando corretamente.

solução!

Não creio que a opção "--recursive" seja necessária nesse caso, tenta remover ela do script "test" no package.json.

Se for utilizar aspas duplas no package.json, lembre de fazer o escape com "\".

O meu script está assim:

"scripts": {
   "test": "set \"NODE_ENV=test\"&&node node_modules/mocha/bin/mocha"
},

Muito Obrigado Daniel.

Agora esta 100%.

Deixei meu script de test do mesmo modelo que o seu e passou tanto pela linha de comando quanto pelo npm test.