Skip to content

CHECK_TYPE macro #131

Open
Open

Description

@grahamreeds

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(...));
}

Activity

  1. pjohnmeyer commented on Sep 6, 2016

    @pjohnmeyer
    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)
       }
  2. killoctal commented on Sep 13, 2016

    @killoctal
    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).

  3. grahamreeds commented on Sep 13, 2016

    @grahamreeds
    ContributorAuthor

    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" notifications@github.com
    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
    .

  4. killoctal commented on Sep 13, 2016

    @killoctal
    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)));

  5. ohz10 commented on Sep 29, 2016

    @ohz10
    Contributor

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

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

  6. ohz10 commented on Sep 29, 2016

    @ohz10
    Contributor

    @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?

  7. pjohnmeyer commented on Oct 4, 2016

    @pjohnmeyer
    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?

  8. grahamreeds commented on Oct 5, 2016

    @grahamreeds
    ContributorAuthor

    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.

  9. pjohnmeyer commented on Jan 13, 2017

    @pjohnmeyer
    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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions