簡単なcmockの例


かなり前からcmockを試してみたかったのですが、なかなかやっていません、汗..
今日思い出して、急いでやってみます.
公式サイトで、インストールパッケージcmock_をダウンロード2_0_204.zip、コンパイルとインストールは必要ありません.しかしcmockはrubyに依存するため,まずrubyをインストールしなければならない.
注意:このインストールパッケージには、サブディレクトリvendor/unity/の下にあるユニットテストツールunityも含まれています.
例の概要:
4ファイル:my_try.h、my_try.c、my_math.h、my_try_ut.c
    my_try.hとmy_try.cは私がテストするコードファイルで、機能はとても簡単で、カプセル化してmy_を呼び出しますmath.hが提供するインタフェース.
例えばmy_try.cの関数my_add()はmy_を直接呼び出しますmath.hが提供するインタフェースadd().
    my_try_ut.cはユニットテストのコードであり、cmockを利用してmy_を実現する.math.hにおけるインタフェースの杭コード、例えばadd().
これでテストの重心をテストしたいmyに置きます.try.c中来.
    
my_math.hのコード:
#ifndef _MY_MATH_
#define _MY_MATH_

int add(int a, int b);
int sub(int a, int b);

#endif

my_try.hのコード:
#ifndef _MY_TRY_
#define _MY_TRY_

int my_add(int a, int b);
int my_sub(int a, int b);

#endif

my_try.cのコード:
#include "my_math.h"
#include "my_try.h"

int my_add(int a, int b)
{
	return add(a, b);
}

int my_sub(int a, int b)
{
	return sub(a, b);
}

my_try_ut.cのコード:
#include "unity.h"
#include "my_try.h"
#include "Mockmy_math.h"

void setUp(void)
{
}

void tearDown(void)
{
}

void test_add()
{
	add_ExpectAndReturn(1, 2, 2);//   , add(1,2)  2
	TEST_ASSERT_EQUAL(3, my_add(1, 2));
}

void test_sub()
{
	sub_ExpectAndReturn(1, 2, -1);
	TEST_ASSERT_EQUAL(-1, my_sub(1, 2));
}

Makefile:
CC = gcc
CFLAGS = -g -Wall

# base dir
CMOCK_DIR = ../cmock/
CMOCK_SRC = $(CMOCK_DIR)/src
UNITY_SRC = $(CMOCK_DIR)/vendor/unity/src
MOCKS_DIR = mocks

TARGET = my_try

# mock file
NAME_DEP = my_math
H_DEP = $(NAME_DEP).h
C_MOCKS = $(MOCKS_DIR)/Mock$(NAME_DEP).c

# UT code
C_UT = $(TARGET)_ut.c
C_RUN = $(TARGET)_runner.c


C_SOURCES = $(UNITY_SRC)/unity.c $(CMOCK_SRC)/cmock.c
C_SOURCES += my_try.c
C_SOURCES += $(C_MOCKS) $(C_UT) $(C_RUN)

C_INCLUDE = -I$(CMOCK_SRC) -I$(UNITY_SRC) -I$(MOCKS_DIR) -I.

C_OBJECTS = $(C_SOURCES:.c=.o)

all: $(TARGET)

$(TARGET): $(C_OBJECTS)
	$(CC) $(CFLAGS) $^ -o $@

%.o:%.c
	$(CC) $(CFLAGS) $(C_INCLUDE) -o $@ -c $<

clean:
	rm -rf $(MOCKS_DIR)
	rm -f $(TARGET) $(C_RUN) $(C_OBJECTS)

mock:
	mkdir -p $(MOCKS_DIR)
	ruby ../cmock/lib/cmock.rb $(H_DEP)
	ruby ../cmock/vendor/unity/auto/generate_test_runner.rb $(C_UT) $(C_RUN)

run:
	./$(TARGET)

実行結果:
$ make run
./my_try
my_try_ut.c:17:test_add:FAIL: Expected 3 Was 2
my_try_ut.c:20:test_sub:PASS
-----------------------
2 Tests 1 Failures 0 Ignored
FAIL

まとめ:
cmockによって、いくつかの外部インタフェースを遮断して、自分のコードに集中することができます.これはとても役に立ちます.上の例は簡単なので、使うのに少しも苦労しませんが、実際のプロジェクトでは、操作するとそうではないと思います.後で、実際のプロジェクトで試してみる機会があります.