googletest icon indicating copy to clipboard operation
googletest copied to clipboard

[Bug]: ON_CALL and EXPECT_CALL cannot be used on the same mock method

Open asoffer opened this issue 1 year ago • 4 comments

Describe the issue

ON_CALL and EXPECT_CALL cannot be used on the same mock method. I would expect that EXPECT_CALL takes precedence if it matches, and otherwise ON_CALL fills in as the default. But at very least, as shown in the repro below, I would expect this to be the case if the matchers for ON_CALL and EXPECT_CALL cover disjoint subsets of the possible input.

Steps to reproduce the problem

https://godbolt.org/z/e6f31EM1E

What version of GoogleTest are you using?

HEAD

What operating system and version are you using?

Not sure, what Godbolt uses under the hood. I've also reproduced this on Linux. I doubt the OS is relevant here.

What compiler and version are you using?

clang 16

What build system are you using?

Godbolt invokes the compiler directly. But I've also reproduced this with bazel 6.1, but I also doubt that's relevant.

Additional context

No response

asoffer avatar Aug 24 '23 00:08 asoffer

WORKED with ON_CALL & EXPECT CALL

its my first time in github open source but this code passed the test with both ON_CALL and EXPECT_CALL

#include "gtest/gtest.h" #include "gmock/gmock.h"

struct S { virtual int f(int n) = 0; };

struct MockS : S { MOCK_METHOD(int, f, (int n), (override)); };

TEST(A, B) { MockS m; EXPECT_CALL(m, f(testing::Ge(10))).Times(2).WillRepeatedly(testing::Return(10)); ON_CALL(m, f(testing::Lt(10))).WillByDefault(testing::Return(0)); ASSERT_EQ(m.f(13) + m.f(13), 20); }

int main(int argc, char** argv) { testing::InitGoogleMock(&argc, argv); return RUN_ALL_TESTS(); }

prabinjamatia avatar Sep 01 '23 09:09 prabinjamatia

WORKED with ON_CALL & EXPECT CALL

its my first time in github open source but this code passed the test with both ON_CALL and EXPECT_CALL

#include "gtest/gtest.h" #include "gmock/gmock.h"

struct S { virtual int f(int n) = 0; };

struct MockS : S { MOCK_METHOD(int, f, (int n), (override)); };

TEST(A, B) { MockS m; EXPECT_CALL(m, f(testing::Ge(10))).Times(2).WillRepeatedly(testing::Return(10)); ON_CALL(m, f(testing::Lt(10))).WillByDefault(testing::Return(0)); ASSERT_EQ(m.f(13) + m.f(13), 20); }

int main(int argc, char** argv) { testing::InitGoogleMock(&argc, argv); return RUN_ALL_TESTS(); }

Your example is different

ASSERT_EQ(m.f(13) + m.f(13), 20);
// vs
EXPECT_EQ(m.f(3) + m.f(13), 10);

If you put 3 into the first f, so that EXPECT_CALL and ON_CALL both are taken into account, it will also fail

artek-koltun avatar Jul 10 '24 08:07 artek-koltun

I'm seeing the same in this simpler repro ( @jsimonlane ):

#include "gtest/gtest.h"
#include "gmock/gmock.h"

struct S {
    virtual int f(int n) = 0;
};

struct MockS : S {
    MOCK_METHOD(int, f, (int n), (override));
};

TEST(A, Bats) {
    MockS m;
    ON_CALL(m, f(3)).WillByDefault([] { return 13; });
    EXPECT_CALL(m, f(1)).WillOnce(testing::Return(10));
    ASSERT_EQ(m.f(3), 13);
    ASSERT_EQ(m.f(1), 10);
}

int main() {
    return RUN_ALL_TESTS();
}

You get this awkward error:

app/example.cpp:15: EXPECT_CALL(m, f(1))...
  Expected arg #0: is equal to 1
           Actual: 3
         Expected: to be called once
           Actual: never called - unsatisfied and active

https://godbolt.org/z/sbcGKG1bs

johnlevidy avatar Aug 07 '24 18:08 johnlevidy