google / googletest

GoogleTest - Google Testing and Mocking Framework
https://google.github.io/googletest/
BSD 3-Clause "New" or "Revised" License
34.96k stars 10.17k forks source link

[Bug]: MSVC ElementsAreArray compilation errors #4529

Closed robjinman closed 6 months ago

robjinman commented 6 months ago

Describe the issue

Use of ElementsAreArray causes compilation errors on Windows with MSVC.

As far as I can tell, I'm doing exactly what is written in the online documentation.

A minimal example

#include <gtest/gtest.h>
#include <gmock/gmock.h>

class MyTestClass : public testing::Test
{
};

class Foo
{
public:
  virtual void bar(const int values[]) {}
};

class MockFoo : public Foo
{
public:
  MOCK_METHOD(void, bar, (const int[]), (override));

};

TEST_F(MyTestClass, thisShouldWork)
{
  const int values[] = { 123, 45 };

  MockFoo foo;
  EXPECT_CALL(foo, bar(testing::ElementsAreArray(values, 2))).Times(1);

  foo.bar(values);
}

Here is the compiler output

PS C:\example\build> cmake --build . --config Debug MSBuild version 17.9.5+33de0b227 for .NET Framework

gmock.vcxproj -> C:\example\build\lib\Debug\gmock.lib gmock_main.vcxproj -> C:\example\build\lib\Debug\gmock_main.lib gtest.vcxproj -> C:\example\build\lib\Debug\gtest.lib gtest_main.vcxproj -> C:\example\build\lib\Debug\gtest_main.lib foo_test.cpp C:\example\src\foo_test.cpp(11,30): warning C4100: 'values': unreferenced formal parameter [C:\example\build\unittests. vcxproj] C:\example\dependencies\Debug\googletest-src\googlemock\include\gmock\gmock-matchers.h(3373,20): error C2825: 'testing: :internal::ElementsAreMatcherImpl<const Container &>::StlContainer': must be a class or namespace when followed by '::' [C:\example\build\unittests.vcxproj] C:\example\dependencies\Debug\googletest-src\googlemock\include\gmock\gmock-matchers.h(3373,20): error C2825: w ith [C:\example\build\unittests.vcxproj] C:\example\dependencies\Debug\googletest-src\googlemock\include\gmock\gmock-matchers.h(3373,20): error C2825: [ [C:\example\build\unittests.vcxproj] C:\example\dependencies\Debug\googletest-src\googlemock\include\gmock\gmock-matchers.h(3373,20): error C2825: Container=const int [C:\example\build\unittests.vcxproj] C:\example\dependencies\Debug\googletest-src\googlemock\include\gmock\gmock-matchers.h(3373,20): error C2825: ] [C:\example\build\unittests.vcxproj] (compiling source file '../src/foo_test.cpp') C:\example\dependencies\Debug\googletest-src\googlemock\include\gmock\gmock-matchers.h(3373,20): the template instantiation context (the oldest one first) is C:\example\src\foo_test.cpp(26,3): see reference to function template instantiation 'testing::internal::ElementsAreArrayMatcher::operator tes ting::Matcher<const int >(void) const<const int>' being compiled C:\example\src\foo_test.cpp(26,68): see the first reference to 'testing::internal::ElementsAreArrayMatcher::operator testing::Matcher< const int >' in 'MyTestClass_thisShouldWork_Test::TestBody' C:\example\dependencies\Debug\googletest-src\googlemock\include\gmock\gmock-matchers.h(3787,35): see reference to class template instantiation 'testing::internal::ElementsAreMatcherImpl<const Container &>' be ing compiled with [ Container=const int * ]

C:\example\dependencies\Debug\googletest-src\googlemock\include\gmock\gmock-matchers.h(3373,34): error C2510: 'StlConta iner': left of '::' must be a class/struct/union [C:\example\build\unittests.vcxproj] (compiling source file '../src/foo_test.cpp')

C:\example\dependencies\Debug\googletest-src\googlemock\include\gmock\gmock-matchers.h(3373,45): error C3646: 'Element' : unknown override specifier [C:\example\build\unittests.vcxproj] (compiling source file '../src/foo_test.cpp')

C:\example\dependencies\Debug\googletest-src\googlemock\include\gmock\gmock-matchers.h(3507,31): error C2146: syntax er ror: missing '>' before identifier 'Element' [C:\example\build\unittests.vcxproj] (compiling source file '../src/foo_test.cpp')

Steps to reproduce the problem

src/main.cpp

#include <gtest/gtest.h>

int main(int argc, char** argv) {
  testing::InitGoogleTest(&argc, argv);

  return RUN_ALL_TESTS();
}

src/foo_test.cpp

#include <gtest/gtest.h>
#include <gmock/gmock.h>

class MyTestClass : public testing::Test
{
};

class Foo
{
public:
  virtual void bar(const int values[]) {}
};

class MockFoo : public Foo
{
public:
  MOCK_METHOD(void, bar, (const int[]), (override));

};

TEST_F(MyTestClass, thisShouldWork)
{
  const int values[] = { 123, 45 };

  MockFoo foo;
  EXPECT_CALL(foo, bar(testing::ElementsAreArray(values, 2))).Times(1);

  foo.bar(values);
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.24)

set(PROJECT_NAME gmock_example)
set(TARGET_NAME unittests)

project(${PROJECT_NAME})

if (NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE "Debug")
endif()

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(FetchContent)
set(FETCHCONTENT_BASE_DIR ${PROJECT_SOURCE_DIR}/dependencies/${CMAKE_BUILD_TYPE})

FetchContent_Declare(googletest
  URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip
  DOWNLOAD_EXTRACT_TIMESTAMP ON
)

FetchContent_MakeAvailable(googletest)

file(GLOB_RECURSE SRCS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")

add_executable(${TARGET_NAME} ${SRCS})

target_link_libraries(${TARGET_NAME} gtest_main gmock_main)
target_compile_options(${TARGET_NAME} PRIVATE "/W4")

Build commands

Run in powershell

cd (mkdir build)
cmake -G "Visual Studio 17 2022" ..
cmake --build . --config Debug

What version of GoogleTest are you using?

1.14.0

What operating system and version are you using?

Windows 11 Enterprise 10.0.22621 Build 22621

What compiler and version are you using?

MSBuild version 17.9.5+33de0b227 for .NET Framework

What build system are you using?

cmake version 3.28.1

Additional context

No response