是否有可能,如果可能的话,如何用一个受测试框架控制的定义替换某个定义?
例如,假设嵌入式系统使用define来访问端口,如下所示:
#define PORTA_CONFIG (*(volatile unsigned int*) (0x1000))
现在,我想确保我的“端口模块”能够正确读/写所述PORTA_CONFIG。如何使用以下内容替换PORTA_CONFIG
volatile unsigned int PORTA_CONFIG;
答案 0 :(得分:1)
对于您使用的生产代码:
//porta_config.h
...
#define PORTA_CONFIG (*(volatile unsigned int*) (0x1000))
在测试项目中,您使用另一个标题:
//porta_config_test.h
...
volatile unsigned int PORTA_CONFIG;
答案 1 :(得分:0)
如果我理解你的意图,你可以这样做:
#define TESTING
int main(){
#ifdef TESTING
volatile unsigned int PORTA_CONFIG;
#else
#define PORTA_CONFIG (*(volatile unsigned int*) (0x1000))
#endif
答案 2 :(得分:0)
与AudioDroid的答案类似,您可以使用一个" facade标头" 包含的不同标头:
portconfig.h 包含数据的标头 - 取决于您需要的目标(或者您是否将其用于测试)
public class MyApplication extends Application {
public static final String LOG_TAG = "MyApp";
public boolean wasInBackground = true;
private AppSession appSession;
private Timer mActivityTransitionTimer;
private TimerTask mActivityTransitionTimerTask;
private final long MAX_ACTIVITY_TRANSITION_TIME_MS = 2000; // Time allowed for transitions
Application.ActivityLifecycleCallbacks activityCallbacks = new Application.ActivityLifecycleCallbacks() {
@Override
public void onActivityResumed(Activity activity) {
if (wasInBackground) {
//Do app-wide came-here-from-background code
appEntered();
}
stopActivityTransitionTimer();
}
@Override
public void onActivityPaused(Activity activity) {
startActivityTransitionTimer();
}
...
};
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(activityCallbacks);
}
public void startActivityTransitionTimer() {
this.mActivityTransitionTimer = new Timer();
this.mActivityTransitionTimerTask = new TimerTask() {
public void run() {
// Task is run when app is exited
wasInBackground = true;
appExited();
}
};
this.mActivityTransitionTimer.schedule(mActivityTransitionTimerTask,
MAX_ACTIVITY_TRANSITION_TIME_MS);
}
public void stopActivityTransitionTimer() {
if (this.mActivityTransitionTimerTask != null) {
this.mActivityTransitionTimerTask.cancel();
}
if (this.mActivityTransitionTimer != null) {
this.mActivityTransitionTimer.cancel();
}
this.wasInBackground = false;
}
private void appEntered() {
Log.i(LOG_TAG, "APP ENTERED");
appSession = new AppSession();
}
private void appExited() {
Log.i(LOG_TAG, "APP EXITED");
appSession.finishAppSession();
// Submit AppSession to server
submitAppSession(appSession);
long sessionLength = (appSession.getT_close() - appSession.getT_open())/1000L;
Log.i(LOG_TAG, "Session Length: " + sessionLength);
}
这些头文件中的每一个都包含这些"定义"因为它们是目标所要求的,例如
<强> portconfig_target_a.h 强>
#ifndef PORTCONFIG_H
#define PORTCONFIG_H
#ifdef TARGET_A
# include <portconfig_target_a.h> /* Use the config for target A */
#elif defined TARGET_B
# include <portconfig_target_b.h> /* Use the config for target B */
#elif defined TEST
# include <portconfig_testing.h> /* Use this instead for testing */
#else
# error "Not supported!" /* Just in case ... */
#endif
#endif /* PORTCONFIG_H */
或
<强> portconfig_testing.h 强>
...
#define PORTA_CONFIG (*(volatile unsigned int*) (0x1000))
...
仅在 一个中心位置 需要...
volatile unsigned int PORTA_CONFIG;
...
,因此 减少维护工作量 。此外,目标/测试代码的使用没有区别,在所有情况下都使用#ifdef
。
除了直接使用#include <portconfig.h>
,您还可以 抽象 将其添加到 功能/宏 。对于 测试 , 可以模拟 这些。
PORTA_CONFIG
这具有抽象的优点,对测试非常有用。
this repository中有一个实现和一些很好的例子,尤其是typedef IOAddress ...
IOData IOData ...
void writePort(IOAddress addr, IOData data);
IOData readPort(IOAddress);
(MockIO,header,implementation,example test) - < em>使用CppUTest 。