Issue
I have a simple Python script check_all_members.py
that calls the Microsoft Graph API to check some Entra ID groups and their members.
"""Check if a group contains any external users."""
import asyncio
from msgraph import GraphServiceClient
from azure.identity import DefaultAzureCredential
GROUP_OBJECT_ID = "a69bc697-1c38-4c81-be00-b2632e04f477"
credential = DefaultAzureCredential()
client = GraphServiceClient(credential)
async def get_group_members():
"""Get all members of a group and check if there are any external users."""
members = await client.groups.by_group_id(GROUP_OBJECT_ID).members.get()
externals = [
member
for member in members.value
if member.user_principal_name.lower().startswith("x")
]
assert not externals, "Group contains external users"
asyncio.run(get_group_members())
I'm trying to write a unit test for this function and here is what I've got so far.
import unittest
from unittest.mock import patch, AsyncMock
from check_all_members import get_group_members
class TestGetGroupMembers(unittest.IsolatedAsyncioTestCase):
@patch("check_all_members.client")
async def test_get_group_members_no_externals(self, mock_client):
mock_members = AsyncMock()
mock_members.get.return_value = {
"value": [
{"id": "123", "user_principal_name": "[email protected]"},
{"id": "456", "user_principal_name": "[email protected]"},
]
}
mock_client.groups.by_group_id.return_value = mock_members
await get_group_members()
mock_client.groups.by_group_id.assert_called_once_with(
"a69bc297-1c88-4c89-be00-b2622e04f475"
)
That seems to work and also fails the test when I change the last assertion. However it should also raise an error since one "user_principal_name" starts with an "x". Unfortunately it doesn't and I cannot figure out why :(
with self.assertRaises(AssertionError):
await get_group_members()
I'm getting the error message and it looks like my returned mock object isn't working properly.
AssertionError: AssertionError not raised
Do you have any ideas?
Solution
- Your mock response structure doesn't match the expected structure returned by
client.groups.by_group_id(GROUP_OBJECT_ID).members.get()
. Theget()
method would typically return anAsyncMock
object that resolves to a response object, not a dictionary directly. So you should mock the.get()
method to return anAsyncMock
which, when awaited, gives the expected dictionary structure. - The
assertRaises
method is correctly used, but the way theget_group_members()
function is structured might not be raising theAssertionError
as expected. It is important to ensure that the assert not externals statement insideget_group_members()
correctly raises anAssertionError
when the condition is met.
import unittest
from unittest.mock import patch, AsyncMock
from check_all_members import get_group_members
class TestGetGroupMembers(unittest.IsolatedAsyncioTestCase):
@patch("check_all_members.client")
async def test_get_group_members_no_externals(self, mock_client):
# Mocking the response structure
mock_members_response = AsyncMock()
mock_members_response.return_value = {
"value": [
{"id": "123", "user_principal_name": "[email protected]"},
{"id": "456", "user_principal_name": "[email protected]"},
]
}
mock_members = AsyncMock()
mock_members.members.get = mock_members_response
mock_client.groups.by_group_id.return_value = mock_members
# Testing for AssertionError
with self.assertRaises(AssertionError):
await get_group_members()
mock_client.groups.by_group_id.assert_called_once_with(
"a69bc697-1c38-4c81-be00-b2632e04f477"
)
Answered By - Yuri R
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.