程序员的修行之路-人生是一场修行

程序员的修行之路-人生是一场修行

人生是一场修行

工作接近10年的时间,不得不感叹时间的飞快,还没来得及回味人生,已经接近中年。这10年来的程序员生涯,感受到过生活的现实和无奈,感受到过孤独和无助,感受到过工作的激情和兴奋,也感受到了辛勤耕耘后收获的喜悦。就这么忙忙碌碌的10年,回想起来,每个片段都历历在目,又觉得是如此恍惚。

在程序员的人生道路上,我承认自己既不是大牛,也不是天才,但是我觉得自己应该是一个勤勤恳恳的耕耘者,这个行业里普普通通的大多数而已。但是不管怎么说,这些年职业的积累,回想并总结一下,也许会帮助那些后来者,少走些弯路。

我想写的,并不是想讲些光鲜亮丽的大道理,而是个人实实在在的人生经历所总结的经验,我本来就是个普普通通的人,所以我将这些经验分享给那些奋斗在一线的普通程序员们。

讲到修行,很容易联想到佛教的僧人,过着与世无争,简单朴素的生活,南无阿弥陀佛,当一天和尚撞一天钟。其实这只是我们看到的表面,佛教最重要的就是修心,六根不净的人,即使剃度,穿上袈裟,心中都很难有佛,别说是成佛了,因此,这跟我们所看到的生活方式没太大关系。佛教的“修行”两个字,讲的真的妙,我读过一行禅师的几本书,很通俗的将佛教思想应用到世俗生活上,成为一种朴素的生活和工作哲学,而这些也正是现代经济社会所缺乏的。

我为什么在这里用修行来描述呢,因为所有的行业,都不可能一步登天,我们这个行业也是一样,需要一点一滴的积累,因此修行的第一层含义就是要沉住气,一步一个脚印,慢慢积累。同时这个行业也有它的特殊性,随时都有可能更新或者颠覆,随时都要学习新的知识,你多年来的工作积累很有可能瞬间就被淘汰了,这时候,修行又有了它的第二层含义,那就是方法论,佛教有三宝,其中之一就是佛法,法就是方法,知识有可能被淘汰,但是经验和方法却是通用的,因此注重知识积累的过程,同时也要兼修方法和经验的总结,这就是我用修行的两层含义。

我将从以下这些角度分别来阐述如何成为优秀程序员需要培养的要素和特质,这些不一定需要你拥有特别的天赋,只需要个人的勤奋和努力再加随时总结和沉淀而已。

目录 下一节

如何在运行时使用 CppUTest 注入模拟类

这是一个简单的指南,教您如何将模拟类注入产品代码中,并让您的产品类在 CppUTest 单元框架下可测试。

下图是类之间的关系。ProductClassB 依赖于 ProductClassA(ProductClassB 调用 ProductClassB.method() 中的 ProductClassA.method1()),现在当我们对 ProductClassB 进行单元测试时,应该模拟 ProductClassA。

下面的代码展示了如何使用 CppUTest 使用新方法来模拟依赖的类。

ProductClassA 有一些方法,如果您希望这些方法可以被模拟,则应将这些方法声明为虚拟方法。

ProductClassA.hpp:

#ifndef _INCLUDE_PRODUCT_A_CLASS_
#define _INCLUDE_PRODUCT_A_CLASS_
#include <string>

class ProductClassA {
public:
ProductClassA() {
}

~ProductClassA() {
}
public:
virtual int method1(const std::string& arg1);
virtual int method2(const std::string& arg1);
};

#endif

ProductClassA.cpp:

#include <iostream>
#include "ProductClassA.hpp"

int ProductClassA::method1(const std::string& arg1) {
std::cout << arg1 << " ProductClassA class method1" <<std::endl;
return 0;
}

int ProductClassA::method2(const std::string& arg1) {
std::cout << arg1 << " ProductClassA class method2" <<std::endl;
return 0;
}

如果你想在对 ProductClassB 进行单元测试时模拟依赖的类 ProductClassA,则应在 ProductClassB 中声明一个具有引用类型的私有 ProductClassA 变量,并且在 ProductClassB 中可以有两个构造函数,一个用于产品代码,一个用于单元测试代码,如下所示。

ProductClassB.hpp:

#include <string>
#include "ProductClassA.hpp"

class ProductClassB {
public:
// for unit test
ProductClassB(ProductClassA& ainstance): _ainstance(ainstance) {
}
// for product code
ProductClassB(): _ainstance(ProductClassA()) {
}
~ProductClassB() {
}

public:
int method();

private:
ProductClassA& _ainstance;
};

ProductClassB.cpp:

#include "ProductClassB.hpp"
#include <iostream>

int ProductClassB::method() {
std::cout<< "this is B class method"<<std::endl;
return this->_ainstance.method1("B invoke");
}

ProductClassAMock类是ProductClassA的派生类,其中的方法将以mock的方式重新实现。

ProductClassAMock.hpp:

#include "ProductClassA.hpp"

class ProductClassAMock : public ProductClassA
{
public:
virtual int method1(const std::string& arg1);
virtual int method2(const std::string& arg1);
};

ProductClassAMock.cpp:

#include "ProductClassAMock.hpp"

#include <iostream>
#include "CppUTest/TestHarness.h"
#include "CppUTestExt/MockSupport.h"

int ProductClassAMock::method1(const std::string& arg1) {
std::cout << arg1 << " ProductClassAMock method1"<<std::endl;
mock().actualCall("method1");
return 0;
}

int ProductClassAMock::method2(const std::string& arg1) {
mock().actualCall("method2");
return 0;
}

ProductClassB 的单元测试将使用测试构造函数在 bInstance 中用模拟类 ProductClassAMock 初始化 _ainstance,然后根据 C++ 多态机制,将 _ainstance.method1() 替换为类 ProductClassAMock 中的 method1。

ProductClassB_unittests.cpp:

#include "ProductClassB.hpp"
#include "ProductClassAMock.hpp"

#include "CppUTest/CommandLineTestRunner.h"
#include "CppUTest/TestHarness.h"
#include "CppUTestExt/MockSupport.h"

TEST_GROUP(BClassFooTests)
{
void teardown()
{
mock().clear();
}
};

TEST(BClassFooTests, MockAsExpected)
{
mock().expectOneCall("method1");
ProductClassAMock aMockInstance;
ProductClassB bInstance(aMockInstance);
bInstance.method();
mock().checkExpectations();
}

int main(int ac, char** av)
{
return CommandLineTestRunner::RunAllTests(ac, av);
}

产品代码只需使用ProductClassB的产品构造函数,bInstance._ainstance将使用真实的类ProductClassA进行初始化。

main.cpp:

#include "ProductClassB.hpp"

int main() {
ProductClassB bInstance();
bInstance.method();
return 0;
}

如何构建代码:

# build main
g++ ProductClassA.cpp ProductClassB.cpp main.cpp -o main

# build unit test
g++ ProductClassA.cpp ProductClassB.cpp ProductClassAMock.cpp ProductClassB_unittests.cpp -lstdc++ -lCppUTest -lCppUTestExt -o testrunner

参考:

本文系本站原创文章,著作版权属于作者,未经允许不得转载,如需转载或引用请注明出处或者联系作者。