Mocking a Stream for Testing











up vote
0
down vote

favorite












Following from Get an istream from a char*, I'm trying to write a mock stream container for some tests which looks as follows:



struct mock_membuf : std::streambuf
{
mock_membuf(char* begin, char* end) {
this->setg(begin, begin, end);
}
};

struct MockStreamContainer{
explicit MockStreamContainer(char* buffer, int offset, int nbytes): m_sbuf(buffer + offset, buffer + offset + nbytes), m_body(&m_sbuf), m_size(nbytes) {}

std::istream& Body() const {
return m_body;
}

int Size() const {
return m_size;
}

mock_membuf m_sbuf; // same as membuf from the question referenced
std::istream& m_body;
int64_t m_size;
};


and will be used as follows:



int main()
{
char buffer = "I'm a buffer with embedded nullsand linen feeds";

auto get_stream = [&buffer](int offset, int nbytes) {
return MockStreamContainer(buffer, offset, nbytes);
};
std::string line;
auto r = get_stream(5, 10);
std::istream& in = r.Body();
while (std::getline(in, line)) {
std::cout << "line: " << line << "n";
}
return 0;
}


The above code is just something I tried(here is a link) and is error ridden - Any suggestions as to how this can be correctly and efficiently implemented?



P.S. As requested the above code throws the following compilation error currently:



main.cpp: In constructor 'MockStreamContainer::MockStreamContainer(char*, int, int)':

main.cpp:17:131: error: invalid initialization of non-const reference of type 'std::istream&' {aka 'std::basic_istream<char>&'} from an rvalue of type 'mock_membuf*'

explicit MockStreamContainer(char* buffer, int offset, int nbytes): m_sbuf(buffer + offset, buffer + offset + nbytes), m_body(&m_sbuf), m_size(nbytes) {}


Edit:
Thanks to @Martin York's answer, I was able to fix the problem by making a minor change: convert m_body to a pointer instead of a reference.










share|improve this question




























    up vote
    0
    down vote

    favorite












    Following from Get an istream from a char*, I'm trying to write a mock stream container for some tests which looks as follows:



    struct mock_membuf : std::streambuf
    {
    mock_membuf(char* begin, char* end) {
    this->setg(begin, begin, end);
    }
    };

    struct MockStreamContainer{
    explicit MockStreamContainer(char* buffer, int offset, int nbytes): m_sbuf(buffer + offset, buffer + offset + nbytes), m_body(&m_sbuf), m_size(nbytes) {}

    std::istream& Body() const {
    return m_body;
    }

    int Size() const {
    return m_size;
    }

    mock_membuf m_sbuf; // same as membuf from the question referenced
    std::istream& m_body;
    int64_t m_size;
    };


    and will be used as follows:



    int main()
    {
    char buffer = "I'm a buffer with embedded nullsand linen feeds";

    auto get_stream = [&buffer](int offset, int nbytes) {
    return MockStreamContainer(buffer, offset, nbytes);
    };
    std::string line;
    auto r = get_stream(5, 10);
    std::istream& in = r.Body();
    while (std::getline(in, line)) {
    std::cout << "line: " << line << "n";
    }
    return 0;
    }


    The above code is just something I tried(here is a link) and is error ridden - Any suggestions as to how this can be correctly and efficiently implemented?



    P.S. As requested the above code throws the following compilation error currently:



    main.cpp: In constructor 'MockStreamContainer::MockStreamContainer(char*, int, int)':

    main.cpp:17:131: error: invalid initialization of non-const reference of type 'std::istream&' {aka 'std::basic_istream<char>&'} from an rvalue of type 'mock_membuf*'

    explicit MockStreamContainer(char* buffer, int offset, int nbytes): m_sbuf(buffer + offset, buffer + offset + nbytes), m_body(&m_sbuf), m_size(nbytes) {}


    Edit:
    Thanks to @Martin York's answer, I was able to fix the problem by making a minor change: convert m_body to a pointer instead of a reference.










    share|improve this question


























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      Following from Get an istream from a char*, I'm trying to write a mock stream container for some tests which looks as follows:



      struct mock_membuf : std::streambuf
      {
      mock_membuf(char* begin, char* end) {
      this->setg(begin, begin, end);
      }
      };

      struct MockStreamContainer{
      explicit MockStreamContainer(char* buffer, int offset, int nbytes): m_sbuf(buffer + offset, buffer + offset + nbytes), m_body(&m_sbuf), m_size(nbytes) {}

      std::istream& Body() const {
      return m_body;
      }

      int Size() const {
      return m_size;
      }

      mock_membuf m_sbuf; // same as membuf from the question referenced
      std::istream& m_body;
      int64_t m_size;
      };


      and will be used as follows:



      int main()
      {
      char buffer = "I'm a buffer with embedded nullsand linen feeds";

      auto get_stream = [&buffer](int offset, int nbytes) {
      return MockStreamContainer(buffer, offset, nbytes);
      };
      std::string line;
      auto r = get_stream(5, 10);
      std::istream& in = r.Body();
      while (std::getline(in, line)) {
      std::cout << "line: " << line << "n";
      }
      return 0;
      }


      The above code is just something I tried(here is a link) and is error ridden - Any suggestions as to how this can be correctly and efficiently implemented?



      P.S. As requested the above code throws the following compilation error currently:



      main.cpp: In constructor 'MockStreamContainer::MockStreamContainer(char*, int, int)':

      main.cpp:17:131: error: invalid initialization of non-const reference of type 'std::istream&' {aka 'std::basic_istream<char>&'} from an rvalue of type 'mock_membuf*'

      explicit MockStreamContainer(char* buffer, int offset, int nbytes): m_sbuf(buffer + offset, buffer + offset + nbytes), m_body(&m_sbuf), m_size(nbytes) {}


      Edit:
      Thanks to @Martin York's answer, I was able to fix the problem by making a minor change: convert m_body to a pointer instead of a reference.










      share|improve this question















      Following from Get an istream from a char*, I'm trying to write a mock stream container for some tests which looks as follows:



      struct mock_membuf : std::streambuf
      {
      mock_membuf(char* begin, char* end) {
      this->setg(begin, begin, end);
      }
      };

      struct MockStreamContainer{
      explicit MockStreamContainer(char* buffer, int offset, int nbytes): m_sbuf(buffer + offset, buffer + offset + nbytes), m_body(&m_sbuf), m_size(nbytes) {}

      std::istream& Body() const {
      return m_body;
      }

      int Size() const {
      return m_size;
      }

      mock_membuf m_sbuf; // same as membuf from the question referenced
      std::istream& m_body;
      int64_t m_size;
      };


      and will be used as follows:



      int main()
      {
      char buffer = "I'm a buffer with embedded nullsand linen feeds";

      auto get_stream = [&buffer](int offset, int nbytes) {
      return MockStreamContainer(buffer, offset, nbytes);
      };
      std::string line;
      auto r = get_stream(5, 10);
      std::istream& in = r.Body();
      while (std::getline(in, line)) {
      std::cout << "line: " << line << "n";
      }
      return 0;
      }


      The above code is just something I tried(here is a link) and is error ridden - Any suggestions as to how this can be correctly and efficiently implemented?



      P.S. As requested the above code throws the following compilation error currently:



      main.cpp: In constructor 'MockStreamContainer::MockStreamContainer(char*, int, int)':

      main.cpp:17:131: error: invalid initialization of non-const reference of type 'std::istream&' {aka 'std::basic_istream<char>&'} from an rvalue of type 'mock_membuf*'

      explicit MockStreamContainer(char* buffer, int offset, int nbytes): m_sbuf(buffer + offset, buffer + offset + nbytes), m_body(&m_sbuf), m_size(nbytes) {}


      Edit:
      Thanks to @Martin York's answer, I was able to fix the problem by making a minor change: convert m_body to a pointer instead of a reference.







      c++ stream






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 19 at 20:48

























      asked Nov 19 at 19:58









      tangy

      738519




      738519
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          1
          down vote



          accepted










          Your member variable m_body is a reference:



          std::istream&    m_body;
          ^ reference


          So you are trying to initialize this reference by creating a temporary in the constructor.



          explicit MockStreamContainer(char* buffer, int offset, int nbytes):
          m_sbuf(buffer + offset, buffer + offset + nbytes),
          m_body(&m_sbuf), // Here you are passing a pointer to `std::streambuf`
          // This is not an `std::istream` so the compiler
          // is trying to create one using the single argument
          // constructor.
          //
          // That worked. So you have a temporary `std::istream` object
          //
          // You can not bind a temporary object to a non const reference
          // hence the compiler error.
          m_size(nbytes)
          {}


          I would do this:



          #include <iostream>

          struct mock_membuf : public std::streambuf
          {
          mock_membuf(char* begin, char* end) {
          this->setg(begin, begin, end);
          }
          };

          struct mock_stream: public std::istream
          {
          mock_membuf streamBuffer;
          public:
          mock_stream(char* buffer, int offset, int nbytes)
          : std::istream(nullptr)
          , streamBuffer(buffer + offset, buffer + offset + nbytes)
          {
          rdbuf(&streamBuffer);
          }
          };

          int main()
          {
          char buffer = "I'm a buffer with embedded nullsand linen feeds";

          std::string line;
          mock_stream in(buffer, 5, 10);
          while (std::getline(in, line)) {
          std::cout << "line: " << line << "n";
          }
          return 0;
          }





          share|improve this answer























          • Thanks for pointing out the problem. What would be the correct way to go about setting up this container then?
            – tangy
            Nov 19 at 20:26










          • Why are you using a reference in the first place?
            – Martin York
            Nov 19 at 20:31










          • Since the copy constructor is deleted for an input stream, I believed that I will have to work with references to avoid problems when passing it around/returning it from functions. I'm sure that I'm just being silly and there's a better way to deal with this.
            – tangy
            Nov 19 at 20:36












          • Actually, based on your suggestion I was able to fix it by making the m_body a pointer. Thanks!
            – tangy
            Nov 19 at 20:43










          • Why not create a MockStream type (rather than a stream holder).
            – Martin York
            Nov 19 at 20:43











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53381777%2fmocking-a-stream-for-testing%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          1
          down vote



          accepted










          Your member variable m_body is a reference:



          std::istream&    m_body;
          ^ reference


          So you are trying to initialize this reference by creating a temporary in the constructor.



          explicit MockStreamContainer(char* buffer, int offset, int nbytes):
          m_sbuf(buffer + offset, buffer + offset + nbytes),
          m_body(&m_sbuf), // Here you are passing a pointer to `std::streambuf`
          // This is not an `std::istream` so the compiler
          // is trying to create one using the single argument
          // constructor.
          //
          // That worked. So you have a temporary `std::istream` object
          //
          // You can not bind a temporary object to a non const reference
          // hence the compiler error.
          m_size(nbytes)
          {}


          I would do this:



          #include <iostream>

          struct mock_membuf : public std::streambuf
          {
          mock_membuf(char* begin, char* end) {
          this->setg(begin, begin, end);
          }
          };

          struct mock_stream: public std::istream
          {
          mock_membuf streamBuffer;
          public:
          mock_stream(char* buffer, int offset, int nbytes)
          : std::istream(nullptr)
          , streamBuffer(buffer + offset, buffer + offset + nbytes)
          {
          rdbuf(&streamBuffer);
          }
          };

          int main()
          {
          char buffer = "I'm a buffer with embedded nullsand linen feeds";

          std::string line;
          mock_stream in(buffer, 5, 10);
          while (std::getline(in, line)) {
          std::cout << "line: " << line << "n";
          }
          return 0;
          }





          share|improve this answer























          • Thanks for pointing out the problem. What would be the correct way to go about setting up this container then?
            – tangy
            Nov 19 at 20:26










          • Why are you using a reference in the first place?
            – Martin York
            Nov 19 at 20:31










          • Since the copy constructor is deleted for an input stream, I believed that I will have to work with references to avoid problems when passing it around/returning it from functions. I'm sure that I'm just being silly and there's a better way to deal with this.
            – tangy
            Nov 19 at 20:36












          • Actually, based on your suggestion I was able to fix it by making the m_body a pointer. Thanks!
            – tangy
            Nov 19 at 20:43










          • Why not create a MockStream type (rather than a stream holder).
            – Martin York
            Nov 19 at 20:43















          up vote
          1
          down vote



          accepted










          Your member variable m_body is a reference:



          std::istream&    m_body;
          ^ reference


          So you are trying to initialize this reference by creating a temporary in the constructor.



          explicit MockStreamContainer(char* buffer, int offset, int nbytes):
          m_sbuf(buffer + offset, buffer + offset + nbytes),
          m_body(&m_sbuf), // Here you are passing a pointer to `std::streambuf`
          // This is not an `std::istream` so the compiler
          // is trying to create one using the single argument
          // constructor.
          //
          // That worked. So you have a temporary `std::istream` object
          //
          // You can not bind a temporary object to a non const reference
          // hence the compiler error.
          m_size(nbytes)
          {}


          I would do this:



          #include <iostream>

          struct mock_membuf : public std::streambuf
          {
          mock_membuf(char* begin, char* end) {
          this->setg(begin, begin, end);
          }
          };

          struct mock_stream: public std::istream
          {
          mock_membuf streamBuffer;
          public:
          mock_stream(char* buffer, int offset, int nbytes)
          : std::istream(nullptr)
          , streamBuffer(buffer + offset, buffer + offset + nbytes)
          {
          rdbuf(&streamBuffer);
          }
          };

          int main()
          {
          char buffer = "I'm a buffer with embedded nullsand linen feeds";

          std::string line;
          mock_stream in(buffer, 5, 10);
          while (std::getline(in, line)) {
          std::cout << "line: " << line << "n";
          }
          return 0;
          }





          share|improve this answer























          • Thanks for pointing out the problem. What would be the correct way to go about setting up this container then?
            – tangy
            Nov 19 at 20:26










          • Why are you using a reference in the first place?
            – Martin York
            Nov 19 at 20:31










          • Since the copy constructor is deleted for an input stream, I believed that I will have to work with references to avoid problems when passing it around/returning it from functions. I'm sure that I'm just being silly and there's a better way to deal with this.
            – tangy
            Nov 19 at 20:36












          • Actually, based on your suggestion I was able to fix it by making the m_body a pointer. Thanks!
            – tangy
            Nov 19 at 20:43










          • Why not create a MockStream type (rather than a stream holder).
            – Martin York
            Nov 19 at 20:43













          up vote
          1
          down vote



          accepted







          up vote
          1
          down vote



          accepted






          Your member variable m_body is a reference:



          std::istream&    m_body;
          ^ reference


          So you are trying to initialize this reference by creating a temporary in the constructor.



          explicit MockStreamContainer(char* buffer, int offset, int nbytes):
          m_sbuf(buffer + offset, buffer + offset + nbytes),
          m_body(&m_sbuf), // Here you are passing a pointer to `std::streambuf`
          // This is not an `std::istream` so the compiler
          // is trying to create one using the single argument
          // constructor.
          //
          // That worked. So you have a temporary `std::istream` object
          //
          // You can not bind a temporary object to a non const reference
          // hence the compiler error.
          m_size(nbytes)
          {}


          I would do this:



          #include <iostream>

          struct mock_membuf : public std::streambuf
          {
          mock_membuf(char* begin, char* end) {
          this->setg(begin, begin, end);
          }
          };

          struct mock_stream: public std::istream
          {
          mock_membuf streamBuffer;
          public:
          mock_stream(char* buffer, int offset, int nbytes)
          : std::istream(nullptr)
          , streamBuffer(buffer + offset, buffer + offset + nbytes)
          {
          rdbuf(&streamBuffer);
          }
          };

          int main()
          {
          char buffer = "I'm a buffer with embedded nullsand linen feeds";

          std::string line;
          mock_stream in(buffer, 5, 10);
          while (std::getline(in, line)) {
          std::cout << "line: " << line << "n";
          }
          return 0;
          }





          share|improve this answer














          Your member variable m_body is a reference:



          std::istream&    m_body;
          ^ reference


          So you are trying to initialize this reference by creating a temporary in the constructor.



          explicit MockStreamContainer(char* buffer, int offset, int nbytes):
          m_sbuf(buffer + offset, buffer + offset + nbytes),
          m_body(&m_sbuf), // Here you are passing a pointer to `std::streambuf`
          // This is not an `std::istream` so the compiler
          // is trying to create one using the single argument
          // constructor.
          //
          // That worked. So you have a temporary `std::istream` object
          //
          // You can not bind a temporary object to a non const reference
          // hence the compiler error.
          m_size(nbytes)
          {}


          I would do this:



          #include <iostream>

          struct mock_membuf : public std::streambuf
          {
          mock_membuf(char* begin, char* end) {
          this->setg(begin, begin, end);
          }
          };

          struct mock_stream: public std::istream
          {
          mock_membuf streamBuffer;
          public:
          mock_stream(char* buffer, int offset, int nbytes)
          : std::istream(nullptr)
          , streamBuffer(buffer + offset, buffer + offset + nbytes)
          {
          rdbuf(&streamBuffer);
          }
          };

          int main()
          {
          char buffer = "I'm a buffer with embedded nullsand linen feeds";

          std::string line;
          mock_stream in(buffer, 5, 10);
          while (std::getline(in, line)) {
          std::cout << "line: " << line << "n";
          }
          return 0;
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 19 at 20:47

























          answered Nov 19 at 20:22









          Martin York

          195k66264479




          195k66264479












          • Thanks for pointing out the problem. What would be the correct way to go about setting up this container then?
            – tangy
            Nov 19 at 20:26










          • Why are you using a reference in the first place?
            – Martin York
            Nov 19 at 20:31










          • Since the copy constructor is deleted for an input stream, I believed that I will have to work with references to avoid problems when passing it around/returning it from functions. I'm sure that I'm just being silly and there's a better way to deal with this.
            – tangy
            Nov 19 at 20:36












          • Actually, based on your suggestion I was able to fix it by making the m_body a pointer. Thanks!
            – tangy
            Nov 19 at 20:43










          • Why not create a MockStream type (rather than a stream holder).
            – Martin York
            Nov 19 at 20:43


















          • Thanks for pointing out the problem. What would be the correct way to go about setting up this container then?
            – tangy
            Nov 19 at 20:26










          • Why are you using a reference in the first place?
            – Martin York
            Nov 19 at 20:31










          • Since the copy constructor is deleted for an input stream, I believed that I will have to work with references to avoid problems when passing it around/returning it from functions. I'm sure that I'm just being silly and there's a better way to deal with this.
            – tangy
            Nov 19 at 20:36












          • Actually, based on your suggestion I was able to fix it by making the m_body a pointer. Thanks!
            – tangy
            Nov 19 at 20:43










          • Why not create a MockStream type (rather than a stream holder).
            – Martin York
            Nov 19 at 20:43
















          Thanks for pointing out the problem. What would be the correct way to go about setting up this container then?
          – tangy
          Nov 19 at 20:26




          Thanks for pointing out the problem. What would be the correct way to go about setting up this container then?
          – tangy
          Nov 19 at 20:26












          Why are you using a reference in the first place?
          – Martin York
          Nov 19 at 20:31




          Why are you using a reference in the first place?
          – Martin York
          Nov 19 at 20:31












          Since the copy constructor is deleted for an input stream, I believed that I will have to work with references to avoid problems when passing it around/returning it from functions. I'm sure that I'm just being silly and there's a better way to deal with this.
          – tangy
          Nov 19 at 20:36






          Since the copy constructor is deleted for an input stream, I believed that I will have to work with references to avoid problems when passing it around/returning it from functions. I'm sure that I'm just being silly and there's a better way to deal with this.
          – tangy
          Nov 19 at 20:36














          Actually, based on your suggestion I was able to fix it by making the m_body a pointer. Thanks!
          – tangy
          Nov 19 at 20:43




          Actually, based on your suggestion I was able to fix it by making the m_body a pointer. Thanks!
          – tangy
          Nov 19 at 20:43












          Why not create a MockStream type (rather than a stream holder).
          – Martin York
          Nov 19 at 20:43




          Why not create a MockStream type (rather than a stream holder).
          – Martin York
          Nov 19 at 20:43


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53381777%2fmocking-a-stream-for-testing%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          404 Error Contact Form 7 ajax form submitting

          How to know if a Active Directory user can login interactively

          TypeError: fit_transform() missing 1 required positional argument: 'X'