Skip to content

Commit 34c2fab

Browse files
test: add unit tests for DataverseClient
Added comprehensive unit tests for the DataverseClient class in tests/unit/test_client.py. These tests mock the internal _ODataClient to verify that the public API methods (create, get, update, delete) correctly delegate to the underlying OData implementation.
1 parent 8aa9945 commit 34c2fab

1 file changed

Lines changed: 131 additions & 0 deletions

File tree

tests/unit/test_client.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT license.
3+
4+
import unittest
5+
from unittest.mock import MagicMock
6+
7+
from azure.core.credentials import TokenCredential
8+
9+
from PowerPlatform.Dataverse.client import DataverseClient
10+
11+
12+
class TestDataverseClient(unittest.TestCase):
13+
def setUp(self):
14+
"""Set up test fixtures before each test method."""
15+
# Create mock credential
16+
self.mock_credential = MagicMock(spec=TokenCredential)
17+
self.base_url = "https://example.crm.dynamics.com"
18+
19+
# Initialize the client under test
20+
self.client = DataverseClient(self.base_url, self.mock_credential)
21+
22+
# Mock the internal _odata client
23+
# This ensures we verify logic without making actual HTTP calls
24+
self.client._odata = MagicMock()
25+
26+
def test_create_single(self):
27+
"""Test create method with a single record."""
28+
# Setup mock return values
29+
# _create must return a GUID string
30+
self.client._odata._create.return_value = "00000000-0000-0000-0000-000000000000"
31+
# _entity_set_from_schema_name should return the plural entity set name
32+
self.client._odata._entity_set_from_schema_name.return_value = "accounts"
33+
34+
# Execute test
35+
self.client.create("account", {"name": "Contoso Ltd"})
36+
37+
# Verify
38+
# Ensure _entity_set_from_schema_name was called and its result ("accounts") was passed to _create
39+
self.client._odata._create.assert_called_once_with(
40+
"accounts", "account", {"name": "Contoso Ltd"}
41+
)
42+
43+
def test_create_multiple(self):
44+
"""Test create method with multiple records."""
45+
payloads = [{"name": "Company A"}, {"name": "Company B"}, {"name": "Company C"}]
46+
47+
# Setup mock return values
48+
# _create_multiple must return a list of GUID strings
49+
self.client._odata._create_multiple.return_value = [
50+
"00000000-0000-0000-0000-000000000001",
51+
"00000000-0000-0000-0000-000000000002",
52+
"00000000-0000-0000-0000-000000000003",
53+
]
54+
self.client._odata._entity_set_from_schema_name.return_value = "accounts"
55+
56+
# Execute test
57+
self.client.create("account", payloads)
58+
59+
# Verify
60+
self.client._odata._create_multiple.assert_called_once_with("accounts", "account", payloads)
61+
62+
def test_update_single(self):
63+
"""Test update method with a single record."""
64+
self.client.update("account", "00000000-0000-0000-0000-000000000000", {"telephone1": "555-0199"})
65+
self.client._odata._update.assert_called_once_with(
66+
"account", "00000000-0000-0000-0000-000000000000", {"telephone1": "555-0199"}
67+
)
68+
69+
def test_update_multiple(self):
70+
"""Test update method with multiple records (broadcast)."""
71+
ids = [
72+
"00000000-0000-0000-0000-000000000001",
73+
"00000000-0000-0000-0000-000000000002",
74+
]
75+
changes = {"statecode": 1}
76+
77+
self.client.update("account", ids, changes)
78+
self.client._odata._update_by_ids.assert_called_once_with("account", ids, changes)
79+
80+
def test_delete_single(self):
81+
"""Test delete method with a single record."""
82+
self.client.delete("account", "00000000-0000-0000-0000-000000000000")
83+
self.client._odata._delete.assert_called_once_with("account", "00000000-0000-0000-0000-000000000000")
84+
85+
def test_delete_multiple(self):
86+
"""Test delete method with multiple records."""
87+
ids = [
88+
"00000000-0000-0000-0000-000000000001",
89+
"00000000-0000-0000-0000-000000000002",
90+
]
91+
# Mock return value for bulk delete job ID
92+
self.client._odata._delete_multiple.return_value = "job-guid-123"
93+
94+
job_id = self.client.delete("account", ids)
95+
96+
self.client._odata._delete_multiple.assert_called_once_with("account", ids)
97+
self.assertEqual(job_id, "job-guid-123")
98+
99+
def test_get_single(self):
100+
"""Test get method with a single record ID."""
101+
# Setup mock return value
102+
expected_record = {"accountid": "00000000-0000-0000-0000-000000000000", "name": "Contoso"}
103+
self.client._odata._get.return_value = expected_record
104+
105+
result = self.client.get("account", "00000000-0000-0000-0000-000000000000")
106+
107+
self.client._odata._get.assert_called_once_with("account", "00000000-0000-0000-0000-000000000000", select=None)
108+
self.assertEqual(result, expected_record)
109+
110+
def test_get_multiple(self):
111+
"""Test get method for querying multiple records."""
112+
# Setup mock return value (iterator)
113+
expected_batch = [{"accountid": "1", "name": "A"}, {"accountid": "2", "name": "B"}]
114+
self.client._odata._get_multiple.return_value = iter([expected_batch])
115+
116+
# Execute query
117+
result_iterator = self.client.get("account", filter="statecode eq 0", top=10)
118+
119+
# Consume iterator to verify content
120+
results = list(result_iterator)
121+
122+
self.client._odata._get_multiple.assert_called_once_with(
123+
"account",
124+
select=None,
125+
filter="statecode eq 0",
126+
orderby=None,
127+
top=10,
128+
expand=None,
129+
page_size=None,
130+
)
131+
self.assertEqual(results, [expected_batch])

0 commit comments

Comments
 (0)