让我假设我有一个c源文件(测试中的源文件),内容为:
uint8 reg1 = I2CRead(20)
uint8 reg2 = I2CRead(24)
uint8 reg3 = I2CRead(28)
if (reg1 != 0x10) || (reg2 != 0x11) || (reg3 != 0x12)
{
register content wrong ...
}
else
{
register content is OK...
}
I2CRead()函数构造如下:
uint8 I2CRead (uint8 address)
{
I2C_Hw_Istance()->DTR = address //DTR = Data Transmit Register
return I2C_Hw_Instance()-> DRR //DRR = Data Receive Register
}
现在我正在尝试编写一个单元测试(使用cpputest框架),我想“伪造”函数读回的值 I2CRead(),以便满足if()中的所有相等表达式。
单元测试文件与“测试中的源文件”隔离,但我可以通过特殊方式访问以下函数 在被测源文件中: I2C_Hw_Instance()。
使用此功能,我可以通过以下方式“伪造”单元测试文件中的寄存器值:
I2C_Hw_Istance()->DTR = 20;
I2C_Hw_Istance()->DRR = 0x10;
因为我连续调用了3个 I2CRead()函数,所以我需要分别通过每个 I2CRead()调用来伪造DTR和DRR。 所以这意味着单元测试文件需要知道何时调用下一个 I2CRead()函数才能操作值 DTR和DRR。
如何做到这一般,任何想法?
我的想法是有一种伪造文件,它与单元测试一起构建(只是“概念性”):
FakeFile.c
void fakeRegisters()
{
if first call of I2CRead() than:
I2C_Hw_Istance()->DTR = 20;
I2C_Hw_Istance()->DRR = 0x10;
if second call of I2CRead()than:
I2C_Hw_Istance()->DTR = 24;
I2C_Hw_Istance()->DRR = 0x11;
if tird call of I2CRead() than:
I2C_Hw_Istance()->DTR = 28;
I2C_Hw_Istance()->DRR = 0x12;
}
答案 0 :(得分:1)
您需要选择I2CRead()
的实现:
uint8_t I2CRead_i2c(uint8_t address)
{
I2C_Hw_Istance()->DTR = address //DTR = Data Transmit Register
return I2C_Hw_Instance()-> DRR //DRR = Data Receive Register
}
uint8_t I2CRead_fake(uint8_t address)
{
switch (address) {
case 20: return 0x10;
case 24: return 0x11;
case 28: return 0x12;
}
fail_test(); /* however you do this in your xUnit */
}
现在,在您的代码中,您通常使用“真实”实现:
uint8 (*I2CRead)(uint8) = I2CRead_i2c;
运行测试时,需要注入模拟实现:
I2CRead = I2CRead_fake;
这是最简单的虚假实现之一;如果你需要它,你可以使用各种各样的伪造品(你可能想要一个包含你的寄存器内容的数组,以便你可以测试初学者的成功和失败路径。)