Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method call verification with QString parameter #68

Closed
reneme opened this issue Jun 20, 2016 · 2 comments
Closed

Method call verification with QString parameter #68

reneme opened this issue Jun 20, 2016 · 2 comments

Comments

@reneme
Copy link

reneme commented Jun 20, 2016

I am using FakeIt to unit test a Qt based application. Method stubbing based on a QString parameter works like a charm -- i.e. the correct stubbed values are returned. When trying to do method call verification based on a QString parameter I am running into problems though.

Here is a (rather) minimal example:

// interface
class Foo {
  public:
    virtual bool bar(const QString &value) {
        return false;
    }
};

// test code
Mock<Foo> mock;
When(Method(mock, bar)).AlwaysReturn(false);
When(Method(mock, bar).Using(QString("foo"))).AlwaysReturn(true);
CHECK(foo.bar(QString("foo")));  // returns true
CHECK(foo.bar("foo"));           // returns true
CHECK(foo.bar("bar"));           // returns false

Verify(Method(mock, bar)).Exactly(3_Times);                       // works
Verify(Method(mock, bar).Using("foo").Exactly(2_Times);           // fails (0 matches)
Verify(Method(mock, bar).Using(QString("foo")).Exactly(2_Times);  // fails (0 matches)

// maybe lower-level? (i.e Matching()) - crashes with SEGFAULT or SIGABRT
Verify(Method(mock, bar).Matching([](QString val){return val == "foo";}).Exactly(2_Times):
// sometimes prints:
// ASSERT: "size == 0 || offset < 0 || size_t(offset) >= sizeof(QArrayData)" in file /usr/local/opt/qt5/lib/QtCore.framework/Headers/qarraydata.h, line 54

Seems that FakeIt damages the internal structure of the QString object, causing miscounting or crashes in the Verify stage. I tried all kinds of variations of casting or explicit object construction for the method invocations with out any luck.

Any thoughts or ideas? Am I doing something stupid?

-- Many thanks.

@tnovotny
Copy link

tnovotny commented Jul 3, 2016

I have tried reproducing the problem. Thank you for posting non compiling code. Missing declarations (foo), missing Fake( Method( mock, bar ) );missing ')' and ':' instead of ';'.

As far as I can tell the main issue is not with QString, but with dangling pointers. You are passing temporaries into the calls. For me everything works when the parameters are kept alive.

Mock<Foo> mock;
Fake( Method( mock, bar ) );

When( Method( mock, bar ) ).AlwaysReturn( false );

auto foo_str = std::string( "foo" );
auto foo2_str = std::string( "foo" );
auto bar_str = std::string( "bar" );

When( Method( mock, bar ).Using( foo_str ) ).AlwaysReturn( true );

auto & foo = mock.get();

auto bar1 = foo.bar( foo2_str );  // returns true
auto bar2 = foo.bar( foo_str );   // returns true
auto bar3 = foo.bar( bar_str );   // returns false

Verify( Method( mock, bar ) ).Exactly( 3_Times );  // works

auto foo_arr = "foo";

Verify( Method( mock, bar ).Using( foo_arr ) ).Exactly( 2_Times );  // works
Verify( Method( mock, bar ).Using( std::string( "foo" ) ) ).Exactly( 2_Times ); // works  

@FranckRJ
Copy link
Collaborator

I'll centralize the discussion about this known bug in a new issue: #274

@FranckRJ FranckRJ closed this as not planned Won't fix, can't repro, duplicate, stale May 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants