TDD principle, how to make the test fail

105 views Asked by At

I m actually studying TDD and so on, I learn by examples.

Actually I m building a little (very very little) ORM to introduce me to real unit test, with stubs and mock.

I run this way, I played my tests and make some little implementation (getAll method) (fail -> make the test pass -> refactor)

Actually, here's my code :

MongodbAdapter

export default class MongoAdapter{
  getAll(){
    return new Promise((resolve, reject)=>{
      resolve(['a','b','c','d']);
    });
  }
}

MysqlAdapter

export default class MysqlAdapter{

  getAll(){
    return new Promise((resolve, reject)=>{
      resolve(['a','b','c','d','e']);
    });
  }
}

FactoryAdapter class

import MysqlAdapter from './adapters/MysqlAdapter';
import MongoAdapter from './adapters/MongoAdapter';

export default class FactoryAdapter{

  static get(name){
    if(name.toLowerCase() === 'mysql') return new MysqlAdapter();
    if(name.toLowerCase() === 'mongodb') return new MongoAdapter();
    return null;
  }

}

Unit tests associated :

TestMongoAdapter

import FactoryAdapter from '../../app/FactoryAdapter';

let chai = require('chai');
let sinon = require("sinon");
let expect = chai.expect;

/** @test {MongoAdapter} */
describe('MongoAdapter class',function(){

  /** @test {MongoAdapter#getAll} */
  describe('MongoAdapter#getAll',function(){
    it('Expect getAll() to equals [a,b,c,d]',function(done){
      let adapter = FactoryAdapter.get('mongodb');
      adapter.getAll().then((value)=>{
        expect(value).to.deep.equal(['a','b','c','d']);
        done();
      });
    });
  });
});

and so on for the two others. My question isn't on the syntax way in this case.

QUESTIONS

Actually, I want to use DB drivers from MYSQL and MONGODB inside of the concerned adapter. Actually, I know what implementation I should do : passing the driver inside of the constructor method of the Adapter when creating an instance of it in the FactoryAdapter.get

My problem is that from that point, I dont know which test I should write (that should fail) before implementating my code.

1

There are 1 answers

0
inf3rno On BEST ANSWER

Actually you use actually pretty much. :D

The database adapter test is an integration test, not an unit test. You cannot test it in separation from the database... Every test has the same structure (according to phpunit manual), you have a fixture, you run the test on the fixture and make assertions. If you want a test to fail you need to write an assertion what fails. E.g. you have a db fixture, which contains data, and the code should retrieve that data. You write an assertion, which requires the data the code should retrieve from the database. It fails. After that you can work on the code. That's all by the db tests.

If a class uses your db adapters, then you have to mock out the adapter; create a fake class, you fully control. After that you can inject the mock adapter instead of the real one, and test what methods the class calls on it. You can inject the fixtures to the mock adapter. E.g. you set that getAll returns a Promise with some data instead of accessing the database and sending queries for the data.

I see you use sinon. Here is the docs about mocks http://sinonjs.org/docs/#mocks-api .