Unit Testing a C++ Database Application with Unit Testing a C++ - - PowerPoint PPT Presentation

unit testing a c database application with unit testing a
SMART_READER_LITE
LIVE PREVIEW

Unit Testing a C++ Database Application with Unit Testing a C++ - - PowerPoint PPT Presentation

Unit Testing a C++ Database Application with Unit Testing a C++ Database Application with Unit Testing a C++ Database Application with Unit Testing a C++ Database Application with Mock Objects Mock Objects Mock Objects Mock Objects Ray


slide-1
SLIDE 1

Unit Testing a C++ Database Application with Mock Objects

Ray Lischner PNSQC October 11, 2011

Unit Testing a C++ Database Application with Mock Objects

Ray Lischner PNSQC October 11, 2011

Unit Testing a C++ Database Application with Mock Objects

Ray Lischner PNSQC October 11, 2011

Unit Testing a C++ Database Application with Mock Objects

Ray Lischner PNSQC October 11, 2011

___________________________________________________________________________________________________________________________ Copies may not be made or distributed for commercial use Excerpt from PNSQC 2011 PNSQC.ORG 1

slide-2
SLIDE 2

Problem

 Write a library to support simple applications

that need to access a SQL database

 Must support unit-testing of applications  Must have a C++ API  Must be easy to write, support  Write a library to support simple applications

that need to access a SQL database

 Must support unit-testing of applications  Must have a C++ API  Must be easy to write, support

Problem

 Write a library to support simple applications

that need to access a SQL database

 Must support unit-testing of applications  Must have a C++ API  Must be easy to write, support  Write a library to support simple applications

that need to access a SQL database

 Must support unit-testing of applications  Must have a C++ API  Must be easy to write, support

___________________________________________________________________________________________________________________________ Copies may not be made or distributed for commercial use Excerpt from PNSQC 2011 PNSQC.ORG 2

slide-3
SLIDE 3

Typical Usage (Simplified)

struct Name { std::string first, last }; typedef std::vector<Name> Names; class DbApp { public: DbApp(db::sql* sql); void get_names(std::string last_name, Names& name); private: static std::string query_; std::auto_ptr<db::sql> sql_; std::auto_ptr<db::statement> stmt_; } struct Name { std::string first, last }; typedef std::vector<Name> Names; class DbApp { public: DbApp(db::sql* sql); void get_names(std::string last_name, Names& name); private: static std::string query_; std::auto_ptr<db::sql> sql_; std::auto_ptr<db::statement> stmt_; }

Typical Usage (Simplified)

struct Name { std::string first, last }; typedef std::vector<Name> Names; class DbApp { public: DbApp(db::sql* sql); void get_names(std::string last_name, Names& name); private: static std::string query_; std::auto_ptr<db::sql> sql_; std::auto_ptr<db::statement> stmt_; } struct Name { std::string first, last }; typedef std::vector<Name> Names; class DbApp { public: DbApp(db::sql* sql); void get_names(std::string last_name, Names& name); private: static std::string query_; std::auto_ptr<db::sql> sql_; std::auto_ptr<db::statement> stmt_; }

___________________________________________________________________________________________________________________________ Copies may not be made or distributed for commercial use Excerpt from PNSQC 2011 PNSQC.ORG 3

slide-4
SLIDE 4

Typical Usage (Simplified)

std::string DbApp::query_( "SELECT * FROM names WHERE last LIKE ?"); DbApp::DbApp(db::sql* sql): sql_(sql), stmt_(sql->prepare(query_)) {} void DbApp::get_names(std::string last_name, Names& names) { stmt_->bind_param(last_name); std::string first, last; stmt_->bind_result(first, last); stmt_->execute(); while (stmt_->fetch()) names.push_back(Name(first, last)); } std::string DbApp::query_( "SELECT * FROM names WHERE last LIKE ?"); DbApp::DbApp(db::sql* sql): sql_(sql), stmt_(sql->prepare(query_)) {} void DbApp::get_names(std::string last_name, Names& names) { stmt_->bind_param(last_name); std::string first, last; stmt_->bind_result(first, last); stmt_->execute(); while (stmt_->fetch()) names.push_back(Name(first, last)); }

Typical Usage (Simplified)

std::string DbApp::query_( "SELECT * FROM names WHERE last LIKE ?"); DbApp::DbApp(db::sql* sql): sql_(sql), stmt_(sql->prepare(query_)) {} void DbApp::get_names(std::string last_name, Names& names) { stmt_->bind_param(last_name); std::string first, last; stmt_->bind_result(first, last); stmt_->execute(); while (stmt_->fetch()) names.push_back(Name(first, last)); } std::string DbApp::query_( "SELECT * FROM names WHERE last LIKE ?"); DbApp::DbApp(db::sql* sql): sql_(sql), stmt_(sql->prepare(query_)) {} void DbApp::get_names(std::string last_name, Names& names) { stmt_->bind_param(last_name); std::string first, last; stmt_->bind_result(first, last); stmt_->execute(); while (stmt_->fetch()) names.push_back(Name(first, last)); }

___________________________________________________________________________________________________________________________ Copies may not be made or distributed for commercial use Excerpt from PNSQC 2011 PNSQC.ORG 4

slide-5
SLIDE 5

Typical Unit Test

db::mock::sql sql; s.store_result(DbApp::query_, "Ray", "Lischner"); s.store_result(DbApp::query_, "Cheryl", "Klipp"); DbApp dbapp(&sql); Names names; dbapp.get_names("name", names); BOOST_CHECK_EQUAL(std::size_t(2), names); BOOST_CHECK_EQUAL(std::string("Ray"), names.at(0).first); BOOST_CHECK_EQUAL(std::string("Cheryl"), names.at(1).first); BOOST_CHECK_EQUAL(std::string("Lischner"), names.at(0).last); BOOST_CHECK_EQUAL(std::string("Klipp"), names.at(1).last); db::mock::sql sql; s.store_result(DbApp::query_, "Ray", "Lischner"); s.store_result(DbApp::query_, "Cheryl", "Klipp"); DbApp dbapp(&sql); Names names; dbapp.get_names("name", names); BOOST_CHECK_EQUAL(std::size_t(2), names); BOOST_CHECK_EQUAL(std::string("Ray"), names.at(0).first); BOOST_CHECK_EQUAL(std::string("Cheryl"), names.at(1).first); BOOST_CHECK_EQUAL(std::string("Lischner"), names.at(0).last); BOOST_CHECK_EQUAL(std::string("Klipp"), names.at(1).last);

Typical Unit Test

db::mock::sql sql; s.store_result(DbApp::query_, "Ray", "Lischner"); s.store_result(DbApp::query_, "Cheryl", "Klipp"); DbApp dbapp(&sql); Names names; dbapp.get_names("name", names); BOOST_CHECK_EQUAL(std::size_t(2), names); BOOST_CHECK_EQUAL(std::string("Ray"), names.at(0).first); BOOST_CHECK_EQUAL(std::string("Cheryl"), names.at(1).first); BOOST_CHECK_EQUAL(std::string("Lischner"), names.at(0).last); BOOST_CHECK_EQUAL(std::string("Klipp"), names.at(1).last); db::mock::sql sql; s.store_result(DbApp::query_, "Ray", "Lischner"); s.store_result(DbApp::query_, "Cheryl", "Klipp"); DbApp dbapp(&sql); Names names; dbapp.get_names("name", names); BOOST_CHECK_EQUAL(std::size_t(2), names); BOOST_CHECK_EQUAL(std::string("Ray"), names.at(0).first); BOOST_CHECK_EQUAL(std::string("Cheryl"), names.at(1).first); BOOST_CHECK_EQUAL(std::string("Lischner"), names.at(0).last); BOOST_CHECK_EQUAL(std::string("Klipp"), names.at(1).last);

___________________________________________________________________________________________________________________________ Copies may not be made or distributed for commercial use Excerpt from PNSQC 2011 PNSQC.ORG 5

slide-6
SLIDE 6

Unit Test Error Cases

db::mock::sql sql; sql.store_result(DbApp::query_, db::mock::error); DbApp dbapp(&sql); Names names; BOOST_CHECK_THROW(dbapp.get_names("name", names), db::exception); db::mock::sql sql; sql.store_result(DbApp::query_, db::mock::error); DbApp dbapp(&sql); Names names; BOOST_CHECK_THROW(dbapp.get_names("name", names), db::exception);

Unit Test Error Cases

db::mock::sql sql; sql.store_result(DbApp::query_, db::mock::error); DbApp dbapp(&sql); Names names; BOOST_CHECK_THROW(dbapp.get_names("name", names), db::exception); db::mock::sql sql; sql.store_result(DbApp::query_, db::mock::error); DbApp dbapp(&sql); Names names; BOOST_CHECK_THROW(dbapp.get_names("name", names), db::exception);

___________________________________________________________________________________________________________________________ Copies may not be made or distributed for commercial use Excerpt from PNSQC 2011 PNSQC.ORG 6

slide-7
SLIDE 7

API

 sql

void connect(connection parameters)

void execute(query)

statement* prepare(query)

 statement

void bind_param(...)

void bind_result(...)

void execute()

bool fetch()

 sql

void connect(connection parameters)

void execute(query)

statement* prepare(query)

 statement

void bind_param(...)

void bind_result(...)

void execute()

bool fetch()

API

 sql

void connect(connection parameters)

void execute(query)

statement* prepare(query)

 statement

void bind_param(...)

void bind_result(...)

void execute()

bool fetch()

 sql

void connect(connection parameters)

void execute(query)

statement* prepare(query)

 statement

void bind_param(...)

void bind_result(...)

void execute()

bool fetch()

___________________________________________________________________________________________________________________________ Copies may not be made or distributed for commercial use Excerpt from PNSQC 2011 PNSQC.ORG 7

slide-8
SLIDE 8

Abstract Interfaces

class sql { public: virtual statement* prepare(std::string const& query) = 0; virtual void execute(std::string const& query) = 0; }; class statement { public: virtual void execute() = 0; virtual bool fetch() = 0; bind? }; class sql { public: virtual statement* prepare(std::string const& query) = 0; virtual void execute(std::string const& query) = 0; }; class statement { public: virtual void execute() = 0; virtual bool fetch() = 0; bind? };

Abstract Interfaces

class sql { public: virtual statement* prepare(std::string const& query) = 0; virtual void execute(std::string const& query) = 0; }; class statement { public: virtual void execute() = 0; virtual bool fetch() = 0; bind? }; class sql { public: virtual statement* prepare(std::string const& query) = 0; virtual void execute(std::string const& query) = 0; }; class statement { public: virtual void execute() = 0; virtual bool fetch() = 0; bind? };

___________________________________________________________________________________________________________________________ Copies may not be made or distributed for commercial use Excerpt from PNSQC 2011 PNSQC.ORG 8

slide-9
SLIDE 9

Impure Abstract Interface

class statement { public: template<class T1, class T2> void bind_param(T1 const& arg1, T2 const& arg2) { params p; p.push_back(param(arg1)); p.push_back(param(arg2)); bind_params(p); } private: void bind_params(params const& p) = 0; }; class statement { public: template<class T1, class T2> void bind_param(T1 const& arg1, T2 const& arg2) { params p; p.push_back(param(arg1)); p.push_back(param(arg2)); bind_params(p); } private: void bind_params(params const& p) = 0; };

Impure Abstract Interface

class statement { public: template<class T1, class T2> void bind_param(T1 const& arg1, T2 const& arg2) { params p; p.push_back(param(arg1)); p.push_back(param(arg2)); bind_params(p); } private: void bind_params(params const& p) = 0; }; class statement { public: template<class T1, class T2> void bind_param(T1 const& arg1, T2 const& arg2) { params p; p.push_back(param(arg1)); p.push_back(param(arg2)); bind_params(p); } private: void bind_params(params const& p) = 0; };

___________________________________________________________________________________________________________________________ Copies may not be made or distributed for commercial use Excerpt from PNSQC 2011 PNSQC.ORG 9

slide-10
SLIDE 10

Real and Mock Classes

sql mysql::sql mock::sql statement mysql::statement mock::statement sql mysql::sql mock::sql statement mysql::statement mock::statement

Real and Mock Classes

sql mysql::sql mock::sql statement mysql::statement mock::statement sql mysql::sql mock::sql statement mysql::statement mock::statement

___________________________________________________________________________________________________________________________ Copies may not be made or distributed for commercial use Excerpt from PNSQC 2011 PNSQC.ORG 10

slide-11
SLIDE 11

Characteristics of a Unit Test

 Fast  Independent  Repeatable  Self-validating (automated)  Timely

Bob Martin. Clean Code. Prentice-Hall, 2008.

 Fast  Independent  Repeatable  Self-validating (automated)  Timely

Bob Martin. Clean Code. Prentice-Hall, 2008.

Characteristics of a Unit Test

 Fast  Independent  Repeatable  Self-validating (automated)  Timely

Bob Martin. Clean Code. Prentice-Hall, 2008.

 Fast  Independent  Repeatable  Self-validating (automated)  Timely

Bob Martin. Clean Code. Prentice-Hall, 2008.

___________________________________________________________________________________________________________________________ Copies may not be made or distributed for commercial use Excerpt from PNSQC 2011 PNSQC.ORG 11

slide-12
SLIDE 12

libdb

 Designed for unit testing  Mock and real libraries designed together

libdb

 Designed for unit testing  Mock and real libraries designed together

___________________________________________________________________________________________________________________________ Copies may not be made or distributed for commercial use Excerpt from PNSQC 2011 PNSQC.ORG 12

slide-13
SLIDE 13

Questions Questions

___________________________________________________________________________________________________________________________ Copies may not be made or distributed for commercial use Excerpt from PNSQC 2011 PNSQC.ORG 13