Hey, I am trying to test a recursive rule in a plu...
# plugins
a
Hey, I am trying to test a recursive rule in a plugin and have a
MockGet
for a
DependenciesRequest -> Targets
call that each iteration calls. However, it looks like only the first call hits my Mock and subsequent calls just return
Targets([])
. Is there a way to do this kind of mocking that I'm unaware of or should I open an issue?
h
I think you’ll need to have as many mocks as there will be calls (which in a deterministic test is a number you know?)
a
I tried that but then it complained about getting more mocks than calls!
h
Oh boy…
I’ll have a quick peek
Related, for some context on recursive rules: https://github.com/pantsbuild/pants/pull/21174
Circling back to this, wouldn’t you expect only the first call to hit your mock? The mock is returning a value for the first call, so no recursion is happening, presumably.
I doubt MockGet is what you want if you’re trying to test the recursive logic itself
Here is an example of a working test for a recursive rule. Note that it tests the real rules, with no mocking, which would seem to be the point.
Copy code
def test_recursive_rules() -> None:
    @dataclass(frozen=True)
    class IntegerIn:
        value: int

    @dataclass(frozen=True)
    class IntegerOut:
        value: int

    @rule
    async def fib(n: IntegerIn) -> IntegerOut:
        if n.value in [0, 1]:
            return IntegerOut(n.value)
        components = await concurrently(
            [
                fib(IntegerIn(n.value - 1)),
                fib(IntegerIn(n.value - 2)),
            ]
        )
        return IntegerOut(components[0].value + components[1].value)

    rule_runner = RuleRunner(
        rules=[
            fib,
            QueryRule(IntegerOut, [IntegerIn]),
        ]
    )
    fib_10 = rule_runner.request(IntegerOut, [IntegerIn(10)])
    assert 55 == fib_10.value