Skip to content
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

Adding unit tests for the ReportSubscriber #11

Merged
merged 13 commits into from
Oct 23, 2024

Conversation

JonasLudwig1998
Copy link
Contributor

No description provided.

'value' => '3',
];

$this->reportSubscriber->getCompanySegmentCondition($filter);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and next similar tests looks like a "coverage only" tests. There is no clear connection between methods mocked an the outcome.
For example here: why the in is called two times, but you return same 'a'? How the expression builder mock corresponds with the incoming data? What is the expected result? What are the expectations of this test case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this one servers as a coverage only test

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The returns 'a' is just used because the test would't continue if no return value was specified for the method

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, to make it somewhat reliable, you should not only check for the methods called, but also the result of the call. Now when somebody refactors the method under test they can introduce new bugs no problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we really wanted to test if the logic in the function is working but not if the doctrine components are working properly. For this, we'd need integration tests, not unit tests. I see the point, and of course it would make sense to implement it. I'll ask the corresponding pm if it makes sense to allocate the resources to implement an extra integration test

Copy link
Contributor

@biozshock biozshock Oct 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to use integration tests. We already have all information that we need, so this is just a puzzle.

public function testGetCompanySegmentConditionWhenOperatorEqualsIn(): void
{
    $filterSubQueryResult = 'filter sub query';
    $filterResult = 'filter result';
    $subQueryResult = 'sub query';
    $filterValue = '3';

    $this->queryBuilderMock->expects(self::once())
        ->method('andWhere')
        ->with($filterSubQueryResult);
    $this->queryBuilderMock->expects(self::once())
        ->method('getSQL')
        ->willReturn($subQueryResult);

    // What is the expected result? -> the builder uses value of the filter, wraps it into the "in" query,
    // then gets whole thing into subquery, and returns the result trough invoking "in" query with the subquery
    $this->exprMock
        ->expects(self::exactly(2))
        ->method('in') // why the in is called two times? -> because first one is a subquery, and second one is a filter.
        ->willReturnCallback(static function (string $field, string $value) use ($subQueryResult, $filterValue, $filterResult, $filterSubQueryResult): string {
            // not same 'a' is returned. and the result is checked in the test.
            if ($field === ReportSubscriber::COMPANY_SEGMENTS_XREF_PREFIX.'.segment_id') {
                // How the expression builder mock corresponds with the incoming data? -> the value gets into the subquery
                self::assertSame($filterValue, $value);

                return $filterSubQueryResult;
            }

            if ($field === ReportSubscriber::COMPANIES_PREFIX.'.id') {
                self::assertSame('('.$subQueryResult.')', $value);

                return $filterResult;
            }

            self::fail('Unknown field: ' . $field);
        });

    $filter = [
        'column'    => 'csx.segment_id',
        'glue'      => 'and',
        'dynamic'   => null,
        'condition' => 'in',
        'value'     => $filterValue,
    ];

    // What are the expectations of this test case? -> Check the filed, field values are correctly placed
    // within the builder and the proper condition is used.
    self::assertSame($filterResult, $this->reportSubscriber->getCompanySegmentCondition($filter));
}

And after seeing this test i will ask in the comment: why you do not use column filter in the method? Thus the bug will be discovered before merging.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the example. The tests are updated now. Regarding your column question I'm not 100% sure to which part of the code you are referring to. Could you be a bit more specific? In case you're suggesting that I should consider the case when the column Company Segments is selected as a column to be displayed in the report, there won't be a problem. Company Segments will be only available as filter, not as report data

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JonasLudwig1998 the column filer is passed in the test case. In the example above it's value is 'csx.segment_id'. The question here is why you do not use the value of the column filter in the method you are testing? For example here: https://github.com/Leuchtfeuer/mautic-CompanySegments-bundle/pull/11/files#diff-8bc8dfe059d8e9152a13b69d1d8617ceb8b3c0a0f9a8e908b88905242c77b178R285

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be implemented now

Copy link
Contributor

@biozshock biozshock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good. Thanks!

@ekkeguembel ekkeguembel merged commit 1b7fb52 into Leuchtfeuer:main Oct 23, 2024
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants