Question

Facing issue while writing test cases using monkey_cognite_patch.


Badge +4

Hi Team, 

We are working on a POC , where we need to create unit test cases where we are facing different issues .For reference we are using code from Cognite Hub

Below attaching our code and output expectations .
Please help with the approach to resolve this issue 

ts_retrieved = [

    TimeSeries(

    id= 3973245479016710,

    external_id= "Brazil:3W:Well-Bore-19B_target_throughput",

    name= "Brazil:3W:Well-Bore-19B_target_throughput",

    is_string= False,

    metadata= {},

    unit= "Barrel",

    asset_id= 3332326574821917,

    is_step= False,

    description= "target volume for a oil well bore",

    security_categories= [],

    data_set_id= 8739280581150161,

    created_time= "2023-05-02 09:37:04.944000",

    last_updated_time= "2023-05-02 09:37:04.944000"

)

]

@pytest.fixture

def cognite_client_mock():

    with monkeypatch_cognite_client() as client:

          client.assets.retrieve().time_series().get().return_value = ts_retrieved

        return client  

 

Method code 
 

        ts_data = c.assets.retrieve(external_id=asset_name).time_series().get(external_id=f'{asset_name}_{ts_type}').to_pandas()

        ts_internal_id = int(ts_data.loc["id"])

        print(f'ts_internal_id {ts_internal_id}')

        print(f'ts_internal_id {ts_data.head(5)}')

Expectation from print is ts_internal_id = 3973245479016710
Actual Output - 


Please provide suggestions on how to achieve the desired output in unit testing the cognite calls.
Thanks.​​​​​​​

 


3 replies

Userlevel 3
Badge

You chain a lot of methods here and so mocking will be a bit entangled as well. First off, you should not call the methods on the mock when setting a return value:

Wrong: client.assets.retrieve().return_value = asset

Correct: client.assets.retrieve.return_value = asset

 

Secondly, you need to think about what is returned by these intermediate chained calls, i.e. you first get an asset object, then you ask for the time series connected to it. This gives you a TimeSeriesList object. On this object, you get the specific time series by using the .get method supplying an identifier etc, etc, etc.

You should probably mock these objects separately, i.e.

mock_ts_list = ...
mock_asset = ...
mock_asset.time_series.return_value = mock_ts_list

client.assets.retrieve.return_value = mock_asset

Hope this have given you a few pointers to mocking! Let me know if you have further follow-up questions.

Badge

I tried the same process like you mentioned above and facing the below issue. Could you please tell more about it. Screenshot provided below.

Error : AttributeError: 'method' object has no attribute 'return_value'

Method Code : 

ts_data = c.assets.retrieve(external_id=asset_name).time_series().get(external_id=f'{asset_name}_{ts_type}').to_pandas()
print(f'ts_internal_id {ts_data}')

conftest file :

mock_ts_list = [
TimeSeries(
id= 11400444674081,
external_id= "Brazil:3W:Well-Bore-19B_estimated_throughput",
name= "Brazil:3W:Well-Bore-19B_estimated_throughput",
is_string= False,
metadata= {},
unit= "Barrel",
asset_id= 33342657421917,
is_step= False,
description= "target volume for a oil well bore",
security_categories= [],
data_set_id= 873920581150161,
created_time= "2023-05-02 09:37:04.944000",
last_updated_time= "2023-05-02 09:37:04.944000"
)]

mock_asset=Asset(
id=397444479016710,
external_id="Brazil:3W:Well-Bore-19B_target_throughput",
name="Brazil:3W:Well-Bore-19B_target_throughput",
metadata={
"some_number": str(9999999),
"some_number_times_2": str(99999999999)
},

)

@pytest.fixture
def cognite_client_mock():
mock_asset_name = "Brazil:3W:Well-Bore-19B"
mock_allowance_unscheduled_events = 0.10
mock_data_set_id= 12345678987643
mock_ts_type= "estimated_throughput"
with monkeypatch_cognite_client() as client:
mock_asset.time_series.return_value = mock_ts_list
client.assets.retrieve.return_value=mock_asset
return client

 

 

Userlevel 3
Badge

Your mock_asset, is not a mock. You could just use MagicMock directly, or better, spec the Asset data class:

from unittest.mock import create_autospec
from cognite.client.data_classes import Asset

mock_asset = create_autospec(Asset, spec_set=True)

 

Reply