Neo
Neo

Reputation: 13

GMock: EXPECT_CALL not called as expected for File *

I was trying this example and the except_call does not satisfy as it is below but the same thing works if i do not give any parameter as this -

EXPECT_CALL(fio, Open(_, _))
  .WillOnce(Return(test_file));
EXPECT_CALL(fio, Write(_, _, _, test_file))
    .WillOnce(Return(sizeof(data)));
EXPECT_CALL(fio, Close(test_file))
  .WillOnce(Return(0));

Any help appreciated , Thank you !!. I have posted the "error message i am getting below"

Here is the entire code.

//Interface

#include <cstdio>
#include <cstddef>


class IFileInputOutput {
public:
  virtual ~IFileInputOutput() {}

  virtual FILE* Open(const char* filename, const char* mode) = 0;
  virtual size_t Write(const void* data, size_t size, size_t num, FILE* file) = 0;
  virtual int Close(FILE* file) = 0;
};


//Implementation
#include <cstdio>

#include "IFileInputOutput.h"

class ImplFileInputOutput : public IFileInputOutput {
public:

  ImplFileInputOutput() {}

  virtual ~ImplFileInputOutput() {}

  virtual FILE* Open(const char* filename, const char* mode) {
      return fopen(filename, mode);
  }

  virtual size_t Write(const void* data, size_t size, size_t num, FILE* file) {
      return fwrite(data, size, num, file);
  }


  virtual int Close(FILE* file) {
      return fclose(file);
  }
};

//class under test Writer.h

#include "IFileInputOutput.h"


class Writer {
public:
    Writer(IFileInputOutput &objfile);
    virtual ~Writer();
    bool WriteBlog(const char* filename, const void* data, size_t size);
    //void WriteNovel();

private:
    IFileInputOutput &objFileInputOutput;
};

//Writer.cpp
#include "Writer.h"



Writer::Writer(IFileInputOutput &objfile):objFileInputOutput(objfile) { }

Writer::~Writer() { }

// Writes a file, returns true on success.
bool Writer::WriteBlog(const char* filename, const void* data, size_t size) {


   FILE* file = objFileInputOutput.Open(filename, "w+");

   if (!file) {
     return false;
   }

   if (objFileInputOutput.Write(data, 1, size, file) != size) {   
     return false;
   }

   if (objFileInputOutput.Close(file) != 0) {
   //if (obj.Close(file) != 0) {
     return false;
   }

   return true;
}

//Mock class
#include <cstddef>
#include <cstdio>

#include <gmock/gmock.h>

#include "IFileInputOutput.h"

class FileInputOutputMock : public IFileInputOutput {

public:

  MOCK_METHOD2(Open, FILE*(const char * filename, const char* mode));
  MOCK_METHOD4(Write, size_t(const void* data, size_t size, size_t num, FILE* file));
  MOCK_METHOD1(Close, int(FILE* file));

};


//Tests



class FileInputOutputTest : public ::testing::Test
{
public:
    void SetUp(){};
    void TearDown(){};

    FileInputOutputTest(){};
    virtual ~FileInputOutputTest(){};


};


TEST_F(FileInputOutputTest, SuccessWorks) {

   FileInputOutputMock fio;
   Writer _objWriter(fio);

  static char data[] = "hello";
  const char* kName = "test.txt";

  FILE* test_file;

    EXPECT_CALL(fio, Open(kName, "w+"))
      .WillOnce(Return(test_file));
    EXPECT_CALL(fio, Write(&data, 1, sizeof(data), test_file))
        .WillOnce(Return(sizeof(data)));
    EXPECT_CALL(fio, Close(test_file))
      .WillOnce(Return(0));


  bool ret = _objWriter.WriteBlog(kName, &data, sizeof(data));

  EXPECT_EQ(true, ret);
}


Error

 * [----------] 1 test from FileInputOutputTest
[ RUN      ] FileInputOutputTest.SuccessWorks
unknown file: Failure

Unexpected mock function call - returning default value.
    Function call: Open(0x47a829 pointing to "test.txt", 0x47ec23 pointing to "w+")
          Returns: NULL
Google Mock tried the following 1 expectation, but it didn't match:

../test/Unit/FileInputOutputTest.cpp:58: EXPECT_CALL(fio, Open(kName, "w+"))...
  Expected arg #1: is equal to 0x47a832 pointing to "w+"
           Actual: 0x47ec23 pointing to "w+"
         Expected: to be called once
           Actual: never called - unsatisfied and active
../test/Unit/FileInputOutputTest.cpp:77: Failure
Value of: ret
  Actual: false
Expected: true
../test/Unit/FileInputOutputTest.cpp:62: Failure
Actual function call count doesn't match EXPECT_CALL(fio, Close(test_file))...
         Expected: to be called once
           Actual: never called - unsatisfied and active
../test/Unit/FileInputOutputTest.cpp:60: Failure
Actual function call count doesn't match EXPECT_CALL(fio, Write(&data, 1, sizeof(data), test_file))...
         Expected: to be called once
           Actual: never called - unsatisfied and active
../test/Unit/FileInputOutputTest.cpp:58: Failure
Actual function call count doesn't match EXPECT_CALL(fio, Open(kName, "w+"))...
         Expected: to be called once
           Actual: never called - unsatisfied and active
[  FAILED  ] FileInputOutputTest.SuccessWorks (1 ms)

Upvotes: 1

Views: 2469

Answers (1)

Marko Popovic
Marko Popovic

Reputation: 4153

The reason for this error is that arguments for function Open are of type char *, so when you specify arguments to be matched, you are actually requesting a matching of pointers. Since you have created the first requested argument kName inside test body and are passing it to the function, that pointer is matched correctly (note that, although this check passes, this is not a correct way to match string literals). However, when matching the second argument, you are actually matching adresses of the first element of a string literal defined in test body and another one which is defined inside the function. Althought they point to the same string literal, these are two distinct addresses and that is why the matching fails.

To correctly match the string literal, use StrEq matcher from gmock. Here is how you do that:

EXPECT_CALL(fio, Open(StrEq(kName), StrEq("w+")))
    .WillOnce(Return(test_file));

Upvotes: 1

Related Questions