class A{};
class Alpha : public A{};
class Aleph : public A{};
class B{};
class Beta : public B{};
class Beth : public B{};
class Foo{
public:
Foo(A* a, B* b) :
_A(a),
_B(b)
{}
private:
std::unique_ptr<A> _A;
std::unique_ptr<B> _B;
}
class MockA{} : public A{};
class MockB{} : public B{};
Test(FooTest, Foo){
MockA mockA;
MockB mockB;
Foo foo(&mockA, &mockB);
}
class MockA{} : public A{};
class MockB{} : public B{};
Test(FooTest, Foo){
std::unique_ptr<MockA>(mockA);
MockA _mockA = mockA.get();
std::unique_ptr<MockB>(mockB);
Foo foo(mockA.release(), mockB.release());
EXPECT_CALL(*_mockA, bar()); //where bar is some mocked out function. Need _mockA since mockA is now a nullptr after the release
/*...more test stuff*/
}
--
---
You received this message because you are subscribed to the Google Groups "Google C++ Mocking Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/googlemock/623e471e-6561-44d7-ab56-fd70de7f51f1%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
syntax correction
Test(FooTest, Foo){
MockA *mockA = new MockA;
MockB *mockB = new MockB;
EXPECT_CALL(*mockA, bar()); // this must be called before passing
// objects into the code to be tested.
Foo foo(mockA, mockB); // [corrected] code to be tested...
// When foo goes out of scope, its destructor will delete mockA and mockB.
}
On 2015 Jan 09, at 2:26 PM, Keith Ray <keit...@gmail.com> wrote:
To view this discussion on the web visit https://groups.google.com/d/msgid/googlemock/4AA80B24-1C64-4363-9D4B-391577C12DC9%40gmail.com.
On 2015 Jan 13, at 10:57 AM, Alex Shaver <alexs...@gmail.com> wrote:Each test will have different EXPECT_CALLs associated with them
--
---
You received this message because you are subscribed to the Google Groups "Google C++ Mocking Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/googlemock/4d30cf5f-5601-4471-a98c-28a88c260bca%40googlegroups.com.
When I do this, the test program crashes. GMock tries to put a mutex lock around the object, and the std::move breaks that mutex, I believe.
class A{
virtual void Arc() = 0;
};
class Mock_A : public A{
MOCK_METHOD0(Arc, void());
};
class Foo{
protected:
Foo(std::unique_ptr<A> a) : _A(std::move(a)){}
std::unique_ptr<A> _A;
void DoStuff(){ _A->Arc(); }
}
TEST(FooTest, DoStuff){
std::unique_ptr<Mock_A> mock_a;
EXPECT_CALL(*mock_a, Arc());
foo(std::move(mock_a));
foo.DoStuff();
}
--
---
You received this message because you are subscribed to the Google Groups "Google C++ Mocking Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/googlemock/15dc5411-903c-4aa0-813e-3a9ce14624bd%40googlegroups.com.
class Bar{
public:
Bar(std::shared_ptr<A> a) : _A(a){}
~Bar() = default;
void DoStuff(){ _A->Arc(); }
std::shared_ptr<A> _A;
}
TEST(Bar, DoStuff){
std::shared_ptr<Mock_A> Alice;
EXPECT_CALL(*Alice, Arc());
Bar bar(Alice);
bar.DoStuff()
}
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+unsubscribe@googlegroups.com.
Right, and this is where I think there's a flaw in the implementation of the testing/mocking infrastructure. The reality, in my actual code, is that it really should be a unique_ptr. Changing it to shared is architecturally incorrect.
In fact (and a new version of this test suite was uploaded to that repo for example) shared_ptr also throws an error.
class Bar{
public:
Bar(std::shared_ptr<A> a) : _A(a){}
~Bar() = default;
void DoStuff(){ _A->Arc(); }
std::shared_ptr<A> _A;
}
TEST(Bar, DoStuff){
std::shared_ptr<Mock_A> Alice;
EXPECT_CALL(*Alice, Arc());
Bar bar(Alice);
bar.DoStuff()
}
throws an error too.
I think, fundamentally, google test seems broken when injecting smart pointers to mock objects. Which is a big flaw for certain design schema, if I want to transfer memory management between objects.
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/googlemock/CAPdGrqq8Yjm3Q34d9Ak%2BBywFa8DJr6wizxehHJcxOeX-qLb5fw%40mail.gmail.com.
Sorry, I just don't have as much experience with the shared_ptr paradigm. But even so, it is an architecturally incorrect choice.
Simply put, Does Google Mock support injection of objects managed by unique_ptr? I don't think so. I certainly welcome a suggestion on how I could properly implement it... but it does seem that google test's clean-up routines, which may be admirable in many other use scenarios, aren't working in a quite reasonable case of injecting smart-memory objects. That is a broken behaviour, if true.
To view this discussion on the web visit https://groups.google.com/d/msgid/googlemock/a9064e38-253a-4ce4-8b89-b81dc022ca53%40googlegroups.com.
class A{
public: virtual void Arc() = 0;
};
class Mock_A : public A{
public: MOCK_METHOD0(Arc, void());
};
class Foo{
public:
Foo(std::unique_ptr<A> a) : _A(std::move(a));
void DoStuff(){_A->Arc();}
std::unique_ptr<A> _A;
};
TEST(Foo, DoStuff){
std::unique_ptr<Mock_A> mock_a;
EXPECT_CALL(*mock_a, Arc());
Foo foo(std::move(mock_a));
foo.DoStuff();
}
class A{public: virtual ~A() {}
virtual void Arc() = 0;};
class Mock_A : public A{public: MOCK_METHOD0(Arc, void());};
class Foo{public:
Foo(std::unique_ptr<A> a) : _a(std::move(a)) {} void DoStuff(){ _a->Arc(); } std::unique_ptr<A> _a;};
TEST(Foo, DoStuff){ std::unique_ptr<Mock_A> mock_a(new Mock_A());
...
I posted a code example several times throughout this discussion, as well as uploaded the exact code that fails to run. I am a little put off at the "help" being offered in such accusatory terms. I don't have much experience with shared_ptr, true. But that was just an experiment to see if such a thing was feasible in the first place. I have more experience with unique_ptr, and I simply have not found a way to make the correct production and test code in that case.
Here is the "concrete complaint" if you wish:
class A{
public: virtual void Arc() = 0;
};
class Mock_A : public A{
public: MOCK_METHOD0(Arc, void());
};
class Foo{
public:
Foo(std::unique_ptr<A> a) : _A(std::move(a));
void DoStuff(){_A->Arc();}
std::unique_ptr<A> _A;
};
TEST(Foo, DoStuff){
std::unique_ptr<Mock_A> mock_a;
EXPECT_CALL(*mock_a, Arc());
Foo foo(std::move(mock_a));
foo.DoStuff();
}That code will fail. I've tried alternatives (again, as mentioned above in several various iterations) including copying the pointer, using just a pointer (not a unique_ptr) to pass into the constructor, and others. If there is a way, I would sincerely appreciate assistance. Something to help me see what I'm missing.
It is only if there is not some way to do this that I think something is not working with the google test framework. Between my own knowledge and the people who made the framework, I expect it's an error on my end. But I cannot, for the life of me, see what it is.
To view this discussion on the web visit https://groups.google.com/d/msgid/googlemock/6adf9b3e-e280-41a5-857a-e8b20dc0938e%40googlegroups.com.
class A{
public: virtual void Arc() = 0;
];
class Mock_A : public A{
public:
Mock_A() = default;
virtual ~Mock_A() = default;
MOCK_METHOD0(Arc, void());
};
class Foo{
public:
Foo(A* a) : _A(std::move(a)){}
void DoStuff(){ _A->Arc(); }
std::unique_ptr<A> _A;
};
TEST(Foo, DoStuff){
Mock_A* Alice = new Mock_A();
EXPECT_CALL(*Mock_A, Arc());
Foo foo(Alice);
foo.DoStuff();
};
/home/amshaver/UniquePtrTesting/Test/UniquePtrTesting_TEST/main.cpp:34: ERROR: this mock object (used in test Foo.DoStuff) should be deleted but never is. Its address is @0x2250820.
ERROR: 1 leaked mock object found at program exit.
...
I've already told you what's wrong with that code, though, and your response was to make a claim about Gmock's "architecturally incorrect choice" instead of actually trying to implement the suggestion.
You have C++ problems, not Gmock problems. That's fine, but please hold off on widening the discussion to Gmock's architecture w.r.t. smart pointers until you've got enough experience to know whether that's true or not.
You need to put something in the unique_ptr before dereferencing it.
Imagine:
Mock_A* mock_a = nullptr;
EXPECT_CALL(*mock_a, Arc());
This is hopefully more obviously wrong.
TEST(){
std::unique_ptr<Mock_A> mock_A;
Mock_A* _mock_A = mock_A.get();
EXPECT_CALL(*_mock_A, Arc());
Foo foo(std::move(mock_A));
foo.DoStuff();
}
...
I've uploaded several variants to the repository https://bitbucket.org/alex_shaver/googletest-uniqueptr. This includes GDB backtraces and google test output.
The closest I can get to a sane compiling program that warps, but not breaks, my code design is the following:
class A{
public: virtual void Arc() = 0;
];
class Mock_A : public A{
public:
Mock_A() = default;
virtual ~Mock_A() = default;
MOCK_METHOD0(Arc, void());
};
class Foo{
public:
Foo(A* a) : _A(std::move(a)){}
void DoStuff(){ _A->Arc(); }
std::unique_ptr<A> _A;
};
TEST(Foo, DoStuff){
Mock_A* Alice = new Mock_A();
EXPECT_CALL(*Mock_A, Arc());
Foo foo(Alice);
foo.DoStuff();
};
which only gives me a/home/amshaver/UniquePtrTesting/Test/UniquePtrTesting_TEST/main.cpp:34: ERROR: this mock object (used in test Foo.DoStuff) should be deleted but never is. Its address is @0x2250820.
ERROR: 1 leaked mock object found at program exit.error in the test.
--
---
You received this message because you are subscribed to the Google Groups "Google C++ Mocking Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/googlemock/24f4e49e-a0d0-493f-a8bc-2fefc7a15a8b%40googlegroups.com.
I've already told you what's wrong with that code, though, and your response was to make a claim about Gmock's "architecturally incorrect choice" instead of actually trying to implement the suggestion.
You have C++ problems, not Gmock problems. That's fine, but please hold off on widening the discussion to Gmock's architecture w.r.t. smart pointers until you've got enough experience to know whether that's true or not.
You need to put something in the unique_ptr before dereferencing it.
Imagine:
Mock_A* mock_a = nullptr;
EXPECT_CALL(*mock_a, Arc());
This is hopefully more obviously wrong.
right, and I have gotten, throughout, why it is wrong.
Obviously, that google test would now see it as a null ptr it can't be used.
So... if it is now a nullptr... how then can I handle it in Google Test so that I can access it for the sake of mock injections? If the ownership is completely within the Foo object, and mock_a now points to null... How am I supposed to use it?
--
---
You received this message because you are subscribed to the Google Groups "Google C++ Mocking Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/googlemock/b0967ece-a378-47b3-9437-8d9168bcddab%40googlegroups.com.
class Mock_A{
Mock_A() = default;
virtual ~Mock_A() = default;
MOCK_METHOD0(Arc, void());
}
class Foo{
Foo(std::unique_ptr<A> alice) : Alice(std::move(alice)){};
virtual ~Foo() = default;
void DoStuff(){ Alice->Arc(); }
std::unique_ptr<A> Alice;
}
TEST(Foo, DoStuff){
std::unique_ptr<Mock_A> Alice(new Mock_A());
EXPECT_CALL(*Alice, Arc());
Foo foo(std::move(Alice));
foo.DoStuff();
}
/home/amshaver/UniquePtrTesting/Test/UniquePtrTesting_TEST/main.cpp:23: ERROR: this mock object (used in test Foo.DoStuff) should be deleted but never is. Its address is @0x20ce820.
ERROR: 1 leaked mock object found at program exit.
...
...
(note too, I was rewriting code into the group text space rather than copy pasting. So the above compiler errors were just my mistranslation from code to post. )
On Wednesday, January 14, 2015 at 10:50:35 AM UTC-5, Alex Shaver wrote:Okay, I definitely had one big glaring error in my prior code. In my attempt to abstract out from my real-world situation, I had forgotten to define constructors and destructors for the class Mock_A;
So, once more into the breach, I have been able to recover (what I think, at least) to be the right production code design.
class Mock_A{
Mock_A() = default;
virtual ~Mock_A() = default;
MOCK_METHOD0(Arc, void());
}
class Foo{
Foo(std::unique_ptr<A> alice) : Alice(std::move(alice)){};
virtual ~Foo() = default;
void DoStuff(){ Alice->Arc(); }
std::unique_ptr<A> Alice;
}
TEST(Foo, DoStuff){std::unique_ptr<Mock_A> Alice(new Mock_A());EXPECT_CALL(*Alice, Arc());Foo foo(std::move(Alice));foo.DoStuff();}
This works, but still returns the stuff about not deleting the object
/home/amshaver/UniquePtrTesting/Test/UniquePtrTesting_TEST/main.cpp:23: ERROR: this mock object (used in test Foo.DoStuff) should be deleted but never is. Its address is @0x20ce820.
ERROR: 1 leaked mock object found at program exit.
I do, of course, sincerely appreciate the help you've provided so far. But this remains my last little sticking point. This isn't *really* an error. The test does pass, of course. So I'm glad of that. But it would be awkward, I suspect, in a larger test suite, to know if and when there was an actual memory leak, and when it's this moved pointer issue.
--
---
You received this message because you are subscribed to the Google Groups "Google C++ Mocking Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/googlemock/1e27e7ea-89e7-4e53-adb3-246925990ba9%40googlegroups.com.
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include <memory>
class A{
public:
virtual void Arc() = 0;
};
class Mock_A : public A{
public:
Mock_A() = default;
virtual ~Mock_A() = default;
MOCK_METHOD0(Arc, void());
};
class Foo{
public:
Foo(std::unique_ptr<A> alice) : Alice(std::move(alice)){}
virtual ~Foo() = default;
void DoStuff(){ Alice->Arc(); }
std::unique_ptr<A> Alice;
};
TEST(Foo, DoStuff){
std::unique_ptr<Mock_A> Alice(new Mock_A());
EXPECT_CALL(*Alice, Arc());
Foo foo(std::move(Alice));
foo.DoStuff();
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from Foo
[ RUN ] Foo.DoStuff
[ OK ] Foo.DoStuff (0 ms)
[----------] 1 test from Foo (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
/home/amshaver/UniquePtrTesting/Test/UniquePtrTesting_TEST/main.cpp:32: ERROR: this mock object (used in test Foo.DoStuff) should be deleted but never is. Its address is @0x25c7820.
ERROR: 1 leaked mock object found at program exit.
class A{
public:
A() = default;
virtual ~A() = default;
virtual void Arc() = 0;
}
...
--
---
You received this message because you are subscribed to the Google Groups "Google C++ Mocking Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/googlemock/9535f3c6-eef9-462a-bbaf-dbaff41bce81%40googlegroups.com.