You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+10-23Lines changed: 10 additions & 23 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -72,15 +72,14 @@ For more information about its usage, see the documentation within the [include/
72
72
73
73
# Testing
74
74
75
-
The singleton has private methods which are designed for testing. These methods are normally inaccessible for production code, which is desired for software stability and quality.
75
+
The singleton has an interface designed for testing only. These interfaces should not be used in production code, because the software stability and quality cannot be guaranteed.
76
76
77
-
The C++ standard states that during explicit template instantiations accessibility checking is not performed. It is possible to exploit this to gain access to private members. Why should we want to get around the accessibility limitation of private members? Because unit tests often need to be able to introspect objects. In the case of this library, the unsafe testing functionality is only accessible by exploiting this behaviour.
78
-
79
-
While it is complicated and impractical to write the template code to access private members - which is a good thing - there are multiple libraries designed to gain access to this functionality for unit tests. The following example shows the usage of the `Reset()` and `Inject()` methods through the [access_private library](https://github.com/martong/access_private/) by [Gábor Márton](https://github.com/martong).
77
+
To access the testing interfaces, test code can include the `singleton_test.hpp` file. This provides access for the tests to use the `::testing::SingletonTestApi` class.
78
+
The following example shows the usage of the `::testing::SingletonTestApi<T>::Reconstruct()` and `::testing::SingletonTestApi<T>::Inject()` methods.
// This returns the real implementation's result from the fresh instance.
111
108
auto realResult2 = instance.MyFunction();
@@ -119,7 +116,7 @@ int main()
119
116
120
117
// This injects the mock implementation.
121
118
// The real instance is destroyed, the `instance` and `instance2` variables are invalidated.
122
-
call_private_static::MySingleton::Inject(&mock);
119
+
SingletonTestApi<MySingleton>::Inject(&mock);
123
120
124
121
// This returns the mock implementation.
125
122
auto& instance3 = MySingleton::Get();
@@ -128,20 +125,10 @@ int main()
128
125
}
129
126
```
130
127
131
-
> [!TIP]
132
-
> When the Singleton has a non-trivial constructor, and the `Reset` function is accessed, then each parameter type must be an r-value reference. For example if `MySingleton`'s constructor is:
> To be able to properly use the `Inject` function, the production code should not cache a reference or pointer to the returned instance. Otherwise the injected mock doesn't take effect and the real instance is used, which is destroyed. This may cause a crash or an other memory corruption style issue.
146
130
147
-
For more examples and "requirements", it is recommended to view this library's [test code](blob/main/test/unit/singleton_test.cpp).
131
+
For more examples and behavioral requirements, it is recommended to view this library's [test code](blob/main/test/unit/singleton_test.cpp).
132
+
133
+
> [!TIP]
134
+
> Earlier versions of this library used the [access_private library](https://github.com/martong/access_private/) by [Gábor Márton](https://github.com/martong) to access the Singleton's testing-only methods through explicit template instantiation's disabled accessibility check. This method is still supported, but it is untested. In version 2.0, the `Reset` method's signature is changed to use universal references, so `&&` must be added after all parameters.
0 commit comments