Marcel
Marcel

Reputation: 37

Python mocking with parameter evaluation

i have a problem when using the patch decorator for mocking a method in python.

the goal is to overwrite the following function call

self.util.database.getLatestPrice(token)

def getLatestPrice(self, token) -> Price | None:

and transport the input parameters.

    def mockedLatestPrice(self, token):
        return self.testUtil.util.database.getHistoryPrice(token, self.time)

    @mock.patch.object(Db, "getLatestPrice", side_effect=mockedLatestPrice)
    def testStrategyWithHistory(self, mock):
        strategy = Strategy(self.testUtil)
        for i in range(1, self.days, 1):
            for j in range(1, 1440, 1):
                logging.info(f"run day {i}, minute {j}:")
                strategy.runStrategy()
                self.nextTime()

i also tried it with side_effect=mockedLatestPrice(token) but it is not working. do i need to use kwargs?

the error message i got is:

TypeError: Test.mockedLatestPrice() missing 1 required positional argument: 'token'

hope s.o. can help

Upvotes: 0

Views: 40

Answers (1)

Anentropic
Anentropic

Reputation: 33833

I think the problem is that mockedLatestPrice is an instance method of the TestCase, but when you pass it as side_effect=mockedLatestPrice that method is not yet bound (because TestCase class is not fully defined yet).

So the token is getting passed to self and the token arg is missing.

Try this:

    def testStrategyWithHistory(self):
        with mock.patch.object(
            Db, "getLatestPrice", side_effect=self.mockedLatestPrice
        ) as mock:
            strategy = Strategy(self.testUtil)
            for i in range(1, self.days, 1):
                for j in range(1, 1440, 1):
                    logging.info(f"run day {i}, minute {j}:")
                    strategy.runStrategy()
                    self.nextTime()

Upvotes: 2

Related Questions