Search code examples
fastapigraphene-sqlalchemystrawberry-graphql

Mocking SQLAlchemy test within Strawberry/FastAPI


I'm working on creating unit tests for a FastAPI, Strawberry, and SQLAlchemy setup. The current API is working and returning data correctly, but I cannot figure out how to mock the underlying database for unit tests. Would love any help/guidance to figure out this issue.

Below is the test code I"m currently working with, which I'm hoping will be enough to solve this issues but happy to post more if it helps. Running this currently will produce and output of ExecutionResult(data=None, errors=[GraphQLError("'NoneType' object is not subscriptable", locations=[SourceLocation(line=3, column=13)], path=['biomarkers'])], extensions={}), which seems to indicate that it is almost working but not quite reaching the mocked data within UnifiedAlchemyMagicMock.

import uuid
import unittest
from unittest import mock
import strawberry
from strawberry.extensions import Extension
from alchemy_mock.mocking import UnifiedAlchemyMagicMock
from app.api.api_v1 import api
from app.models import biomarker as biomarker_models

class MockSession:
    '''Create Mock Session for Db'''
    session = UnifiedAlchemyMagicMock(data=[
        (
            [mock.call.query(biomarker_models.Biomarker)],
            [biomarker_models.Biomarker(
                name="hello",
                id=uuid.UUID('1a8d8791-946c-4fc4-8f5d-1b0c4f5ee2f5'),
                quest_biomarker_code="quest"),
             biomarker_models.Biomarker(
                 name="test",
                 id=uuid.uuid4(),
                 quest_biomarker_code="palazo")]
        )
    ])


class MockRequest(Extension):
    '''Mock Request state for context'''
    def on_request_start(self):
        self.execution_context.context["db"] = MockSession()

    def on_request_end(self):
        self.execution_context.context["db"].close()


class BioMarkerTestCase(unittest.TestCase):
    '''Test Biomarker'''

    def setUp(self) -> None:
        self.strawberry_schema = strawberry.Schema(
                query=api.Query,
                mutation=api.Mutation,
                extensions=[MockRequest],
                types=api.QUERY_TYPE_LIST)

    def test_query_get_all(self) -> None:
        '''test biomarker query'''
        query = """
        query {
            biomarkers {
                id
                name
                whyItMatters
                questBiomarkerCode
                modeOfAcquisition
                questRefRangeLow
                questRefRangeHigh
                optimalRangeLow
                optimalRangeHigh
                withinRangeRecommendations
                belowRangeRecommendations
                aboveRangeRecommendations
                crossReferenceBiomarkers
                notes
                resourcesCited
                measurementUnits
                isCritical
                resultDataType
                critical{
                    id
                    biomarkerId
                    isPriority1
                    priority1Range
                    isPriority2
                    priority2Range
                }
            }
        }
        """
        query_result = query_result = self.strawberry_schema.execute_sync(query)
        self.assertIsNotNone(query_result.data)

Solution

  • When using

    query_result = query_result = self.strawberry_schema.execute_sync(query)
    

    the context_value is defaulted to None, which I think is the cause of your errors.

    try with:

    query_result = query_result = self.strawberry_schema.execute_sync(query, context_value={})