[GO] Embedded Programming by Test Driven Development-Mock & Flash Driver Edition-

Continuation until now.

Embedded programming by test-driven development with googletest Embedded programming by test-driven development with google test Chapter 8

Preface

[Amazon.co.jp: Embedded programming with test-driven development-Agile design learned in C language and object orientation](https://www.amazon.co.jp/%E3%83%86%E3%82%B9 % E3% 83% 88% E9% A7% 86% E5% 8B% 95% E9% 96% 8B% E7% 99% BA% E3% 81% AB% E3% 82% 88% E3% 82% 8B% E7 % B5% 84% E3% 81% BF% E8% BE% BC% E3% 81% BF% E3% 83% 97% E3% 83% AD% E3% 82% B0% E3% 83% A9% E3% 83 % 9F% E3% 83% B3% E3% 82% B0-% E2% 80% 95C% E8% A8% 80% E8% AA% 9E% E3% 81% A8% E3% 82% AA% E3% 83% 96% E3% 82% B8% E3% 82% A7% E3% 82% AF% E3% 83% 88% E6% 8C% 87% E5% 90% 91% E3% 81% A7% E5% AD% A6% E3% 81% B6% E3% 82% A2% E3% 82% B8% E3% 83% A3% E3% 82% A4% E3% 83% AB% E3% 81% AA% E8% A8% AD% E8% A8% 88-James-W-Grenning / dp / 4873116147)

Again, this is the bible for embedded test-driven development. Chapter 10 deals with mocking with the Flash driver as the subject. However, just trying to move the contents written in the book is a certain degree of difficulty. It's broken in various ways, and it doesn't work just by copying the contents of the book! (The completed code is distributed as a sample)

Therefore, I prepared a repository in which the tests were moved one by one. https://github.com/tomoyuki-nakabayashi/TDDforEmbeddedC_FlashDriver

It is troublesome to organize the commit history, so if you want to start from the beginning, start with pass FirstWrite (SHA: cba030eac89b87e6a9d3ce33a0418e99db8c1a0b).

MockIO code

The Mock featured in the book has more than 200 lines and is hard to get along with. googlemock is so good that you can do the same in the next 25 lines or so.

#ifndef TEST_MOCK_MOCK_IO_H_
#define TEST_MOCK_MOCK_IO_H_
#include "gmock/gmock.h"
#include "IO.h"

class MockIO {
public:
  MOCK_METHOD1(IO_Read, ioData(ioAddress));
  MOCK_METHOD2(IO_Write, void(ioAddress, ioData));
};

extern MockIO *mockIO;

extern "C" {
  void IO_Write(ioAddress addr, ioData data)
  {
    return mockIO->IO_Write(addr, data);
  }

  ioData IO_Read(ioAddress addr)
  {
    return mockIO->IO_Read(addr);
  }
}

#endif //  TEST_MOCK_MOCK_IO_H_

It ’s easy, is n’t it?

How to use the mock from the test code

For example, if you want to test that IO_Write (address, data) is called once when you call Flash_Write (address, data) in the code under test, you would do the following:

TEST_F(FlashDriverTest, WriteSucceeds_ReadyImmediately)
{
  EXPECT_CALL(*mockIO, IO_Write(address, data)).Times(1);
  int result = Flash_Write(address, data);
}

It is necessary to prepare the mockIO object in advance. If googlemock reuses objects, it will take over the previous EXPECT_CALL and behave unintentionally. It is easier to recreate each test case.

#include "mock/MockIO.h"
MockIO *mockIO;

class FlashDriverTest : public ::testing::Test
{
  virtual void SetUp()
  {
    mockIO = new MockIO();
  }

  virtual void TearDown()
  {
    delete mockIO;
  }
};

If you set the return value from the mock, set the action as follows: Now when you call IO_Read (), it will return ReadyBit as the return value.

TEST_F(FlashDriverTest, WriteSucceeds_ReadyImmediately)
{
  EXPECT_CALL(*mockIO, IO_Read(StatusRegister)).WillOnce(Return(ReadyBit));
  int result = Flash_Write(address, data);
}

Digression

When mocking a C language function, you need to be careful when handling the mock. I was crazy about it in the past. Please contact me if you have any problems mocking C language functions. You may be able to help. Since you have to put the mock in the global area, if you want to share the mock from multiple test source codes, please define the mock pointer only once somewhere. It seems to behave strangely when running in multithreading, but so far it hasn't been a problem.

You can also include the .c file in the namespace to create a unique mock object in the namespace. This method eliminates the need to share mock objects, but the target .c file is compiled by the c ++ compiler, which is not a strict C test.

I will do the rest of the book from time to time.

Recommended Posts

Embedded Programming by Test Driven Development-Mock & Flash Driver Edition-