Googletest export
Add static_asserts that verify that no class hierarchy contains more than one of {NiceMock, NaggyMock, StrictMock}. This sort of nesting has always been disallowed, but this CL adds a compile-time check to prevent it. PiperOrigin-RevId: 347037822
This commit is contained in:
parent
5a509dbd2e
commit
18f8200e30
@ -63,14 +63,44 @@
|
|||||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "gmock/gmock-spec-builders.h"
|
#include "gmock/gmock-spec-builders.h"
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
template <class MockClass>
|
||||||
|
class NiceMock;
|
||||||
|
template <class MockClass>
|
||||||
|
class NaggyMock;
|
||||||
|
template <class MockClass>
|
||||||
|
class StrictMock;
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
template <typename T>
|
||||||
|
std::true_type StrictnessModifierProbe(const NiceMock<T>&);
|
||||||
|
template <typename T>
|
||||||
|
std::true_type StrictnessModifierProbe(const NaggyMock<T>&);
|
||||||
|
template <typename T>
|
||||||
|
std::true_type StrictnessModifierProbe(const StrictMock<T>&);
|
||||||
|
std::false_type StrictnessModifierProbe(...);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr bool HasStrictnessModifier() {
|
||||||
|
return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
template <class MockClass>
|
template <class MockClass>
|
||||||
class NiceMock : public MockClass {
|
class NiceMock : public MockClass {
|
||||||
public:
|
public:
|
||||||
|
static_assert(
|
||||||
|
!internal::HasStrictnessModifier<MockClass>(),
|
||||||
|
"Can't apply NiceMock to a class hierarchy that already has a "
|
||||||
|
"strictness modifier. See "
|
||||||
|
"https://github.com/google/googletest/blob/master/googlemock/docs/"
|
||||||
|
"cook_book.md#the-nice-the-strict-and-the-naggy-nicestrictnaggy");
|
||||||
NiceMock() : MockClass() {
|
NiceMock() : MockClass() {
|
||||||
::testing::Mock::AllowUninterestingCalls(
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
@ -108,6 +138,13 @@ class NiceMock : public MockClass {
|
|||||||
|
|
||||||
template <class MockClass>
|
template <class MockClass>
|
||||||
class NaggyMock : public MockClass {
|
class NaggyMock : public MockClass {
|
||||||
|
static_assert(
|
||||||
|
!internal::HasStrictnessModifier<MockClass>(),
|
||||||
|
"Can't apply NaggyMock to a class hierarchy that already has a "
|
||||||
|
"strictness modifier. See "
|
||||||
|
"https://github.com/google/googletest/blob/master/googlemock/docs/"
|
||||||
|
"cook_book.md#the-nice-the-strict-and-the-naggy-nicestrictnaggy");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NaggyMock() : MockClass() {
|
NaggyMock() : MockClass() {
|
||||||
::testing::Mock::WarnUninterestingCalls(
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
@ -147,6 +184,12 @@ class NaggyMock : public MockClass {
|
|||||||
template <class MockClass>
|
template <class MockClass>
|
||||||
class StrictMock : public MockClass {
|
class StrictMock : public MockClass {
|
||||||
public:
|
public:
|
||||||
|
static_assert(
|
||||||
|
!internal::HasStrictnessModifier<MockClass>(),
|
||||||
|
"Can't apply StrictMock to a class hierarchy that already has a "
|
||||||
|
"strictness modifier. See "
|
||||||
|
"https://github.com/google/googletest/blob/master/googlemock/docs/"
|
||||||
|
"cook_book.md#the-nice-the-strict-and-the-naggy-nicestrictnaggy");
|
||||||
StrictMock() : MockClass() {
|
StrictMock() : MockClass() {
|
||||||
::testing::Mock::FailUninterestingCalls(
|
::testing::Mock::FailUninterestingCalls(
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
@ -182,34 +225,6 @@ class StrictMock : public MockClass {
|
|||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
|
||||||
};
|
};
|
||||||
|
|
||||||
// The following specializations catch some (relatively more common)
|
|
||||||
// user errors of nesting nice and strict mocks. They do NOT catch
|
|
||||||
// all possible errors.
|
|
||||||
|
|
||||||
// These specializations are declared but not defined, as NiceMock,
|
|
||||||
// NaggyMock, and StrictMock cannot be nested.
|
|
||||||
|
|
||||||
template <typename MockClass>
|
|
||||||
class NiceMock<NiceMock<MockClass> >;
|
|
||||||
template <typename MockClass>
|
|
||||||
class NiceMock<NaggyMock<MockClass> >;
|
|
||||||
template <typename MockClass>
|
|
||||||
class NiceMock<StrictMock<MockClass> >;
|
|
||||||
|
|
||||||
template <typename MockClass>
|
|
||||||
class NaggyMock<NiceMock<MockClass> >;
|
|
||||||
template <typename MockClass>
|
|
||||||
class NaggyMock<NaggyMock<MockClass> >;
|
|
||||||
template <typename MockClass>
|
|
||||||
class NaggyMock<StrictMock<MockClass> >;
|
|
||||||
|
|
||||||
template <typename MockClass>
|
|
||||||
class StrictMock<NiceMock<MockClass> >;
|
|
||||||
template <typename MockClass>
|
|
||||||
class StrictMock<NaggyMock<MockClass> >;
|
|
||||||
template <typename MockClass>
|
|
||||||
class StrictMock<StrictMock<MockClass> >;
|
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||||
|
Loading…
Reference in New Issue
Block a user