Thanks to visit codestin.com
Credit goes to github.com

Skip to content

CHECK_TYPE macro #131

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

Open
grahamreeds opened this issue Sep 6, 2016 · 9 comments
Open

CHECK_TYPE macro #131

grahamreeds opened this issue Sep 6, 2016 · 9 comments

Comments

@grahamreeds
Copy link
Contributor

I was thinking this morning about unit testing a factory class. With a certain set of parameters I need to check that the emitted object is of the correct type. I think this will be similar to the CHECK_EXCEPTION macro.

struct TypeA { };
struct TypeB { };

TEST(MakeSureTypeAIsReturnedWithACertainSetOfParameters)
{
  // ... set parameters
  CHECK_TYPE(TypeA, DoSomethingThatShouldReturnAnObjectOfTypeA(...));
}
@pjohnmeyer
Copy link
Member

I'm assuming that in your example TypeA and TypeB share some inheritance hierarchy, and that DoSomethingThatShouldReturnAnObjectOfTypeA has a co-variant return type. If I'm wrong I may not quite be understanding the use case.

In the past when I've encountered the need to check the type of an object, I just use dynamic_cast. This has always been good enough for my purposes. What do you propose the benefits of CHECK_TYPE would be over something like the below?

   TEST(TypeCheckingReferences)
   {
      CHECK(dynamic_cast<std::ostream&>(std::cout)); // passes
      CHECK(dynamic_cast<std::istream&>(std::cin)); // passes
      CHECK(dynamic_cast<std::ostream&>(std::cin)); // error: Failure in TypeCheckingReferences: Unhandled exception (std::bad_cast) in CHECK(dynamic_cast<std::ostream&>(std::cin))
   }

   TEST(TypeCheckingPointers)
   {
      std::ios_base* p_cout = &std::cout;
      std::ios_base* p_cin = &std::cin;
      CHECK(dynamic_cast<std::ostream*>(p_cout)); // passes
      CHECK(dynamic_cast<std::istream*>(p_cin)); // passes
      CHECK(dynamic_cast<std::ostream*>(p_cin)); // error: Failure in TypeCheckingPtr: dynamic_cast<std::ostream*>(p_cin)
   }

@killoctal
Copy link
Contributor

In my opinion, UnitTest++ is a bit poor in its assertions set. C# for example has plenty of useful Assert.*
It could be great to have some of them, like type match, greater than, lower than.

By the way I would love to have a force-fail assertion, like FAIL("Message"); (but it is off topic).

@grahamreeds
Copy link
Contributor Author

Force fail is CHECK(false);

As for the issue the types do not have to be from a hierarchy. In my use
case it is a factory/parser taking a stream of bytes and spewing out blocks
of data in neat little bundles in a tag despatch fashion.

Sent from my Nexus 6P

On 13 Sep 2016 9:53 a.m., "Gabriel Schlozer" [email protected]
wrote:

In my opinion, UnitTest++ is a bit poor in its assertions set. C# for
example has plenty of useful Assert.*
https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.assert.aspx
It could be great to have some of them, like type match, greater than,
lower than.

By the way I would love to have a force-fail assertion, like
FAIL("Message"); (but it is off topic).


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
#131 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AEy9nGL6d79ueV-ozyQ0CasV_FvdIMgGks5qpmSNgaJpZM4J1iiX
.

@killoctal
Copy link
Contributor

Force fail is CHECK(false);

It is not the same functionality, it should interrupt the test execution so it should better be REQUIRE CHECK(false); but this way does not allow to specify a failure message, it will show "error: CHECK(false);" which is not that expressive...

If you are not sure about the return type, it should be converted to void* before but I am not sure about the result of dynamic_cast in this case :
CHECK(dynamic_cast<type*>(reinterpret_cast<void*>(var)));

@ohz10
Copy link
Contributor

ohz10 commented Sep 29, 2016

In my opinion, UnitTest++ is a bit poor in its assertions set.

@killoctal you say "poor", I say minimalist.

@ohz10
Copy link
Contributor

ohz10 commented Sep 29, 2016

@killoctal If I recall correctly, @pjohnmeyer has toyed around with adding custom failure messages to assertions in the past; perhaps you or he could sketch out what that might look like without introducing new macros?

@pjohnmeyer
Copy link
Member

Force fail with a custom message is currently achievable using throw, assuming you're building UnitTest++ with exception support on and are throwing a std::exception. That said, force fail is off the topic of the thread so let's stay on the main event.

As for the issue the types do not have to be from a hierarchy. In my use
case it is a factory/parser taking a stream of bytes and spewing out blocks
of data in neat little bundles in a tag despatch fashion.

@grahamreeds Can you post a minimal example of what the target code and the proposed unit test would look like?

@grahamreeds
Copy link
Contributor Author

grahamreeds commented Oct 5, 2016

Pretty much as it is in my original post. The idea revolves around messages coming in from udp source and a parser creating a tag that is passed to the dispatcher.

Actual code would look like

struct message_a { };
std::vector<uint8_t> binary_data = { ... };
CHECK_TYPE(message_a, udp.parse(binary_data));

In my little toy project neither message_a or message_b are related via a hierarchy but still go through the same dispatch routine.

@pjohnmeyer
Copy link
Member

If compile-time dispatch techniques are in play, can't the compiler just be the check here?

struct message_a {};
std::vector<uint8_t> binary_data = { ... };
message_a parsed_data = udp.parse(binary_data); // compile fails if wrong type

Or is that not what you meant?

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

4 participants