It’s a well-known fact, that communication with an external system is a critical functionality within modern systems. As OData (Open Data Protocol) rises in popularity due to its numerous advantages, more systems choose to expose OData API. Consuming such endpoints is recognized to be extremely easy, as we have a standardized query framework which allows us to get only the data we need from the server.
Unit testing of such integrations, especially within micro services based system, can introduce a lot of benefits. Those include cost savings, facilitating changes, pushing quality upstream, to name a few. And, most importantly, it can save a lot of time as broken queries are found before integration or regression tests.
That is why many development engineers tend to consider testing of communication with such system integration tests. Unit test approach for such a functionality would usually consist of checking if our query builder built a correct query. For example:
However, the issue occurs when we want to test method which provides the query string and operates on returned data in particular – how we can mock our web client abstraction.
First, let’s consider what elements our puzzle needs.
To mock something like WebClient we would need to provide
1) List of entities backed. In more advanced scenarios we can provide mock for the whole data context.
2) Model of backend data so we can resolve provided url.
What we want to end up with is similar to the following:
First of all, let’s consider our ODataModelHelper class. We need to generate any implementation of IEdmModel so our mock client will be able to resolve entities based on ODataPath. This is relatively simple as we can use the same class, we would use to create actual OData service.
What we want to do in our mock WebClient is following:
1) Find IEdmType associated with our entity type.
2) Create ODataQueryOptions based on provider url and IEdmModel.
3) Apply those options to mocked DataSet.
Let’s translate it to code
ODataQueryOptions, which is the core of our mock, takes two arguments in constructor. The first one is ODataQueryContext. This class is responsible for generating correct path for correct object type.
The second parameter is HttpRequestMessage. If you are familiar with MVC implementation in .NET, you know, that every HttpMessage is highly dependent on HttpConfiguration. In standard scenario, HttpConfiguration is mostly built based on web.config and during AppStart method, which we don’t have in our mock scenario. This means we have to manually create HttpConfiguration object and supply it to our HttpRequestMessage.
As ApplyQueryToEntities is generic, you can use that on any type you need.
This testing approach may also come in handy when you need to test the model builder for your backend API.
As a conclusion, the unit testing of the OData client is a valuable step in making your integrations work to the fullest. As it can be seen, it’s not so difficult to expand your test coverage a little bit further to make it really work for real-life cases. Using this approach you can still use your implementation of repository and provide mock object at a lower level.
Pursuant to art. 13, sec. 1 and 2 of the Regulation of the European Parliament and the Council of the European Union (Regulation (EU) 2016/679) of April 27 2016 with respect to the processing of personal data and the free flow of such data, as well as the repealing of Directive 95/46/WE; (general data protection regulation, referred to herein as GDPR) (EU Official Journal UE L119/1), we inform you that:
1. The Administrator of your personal data is “IT Kontrakt” Sp. z o.o., with its registered office in Wrocław, ul. Gwiaździsta 66, 53-413 Wrocław, e-mail: email@example.com
2. Your personal data will be processed in accordance with GDPR for the purpose of sending you commercial and marketing information, in particular for the purpose of contacting you by e-mail and informing you of services, products, and events involving the Administrator and its personnel pursuant to art. 6 sec. 1 item a) of GDPR
3. The coordinator of activities related to the protection of personal data undertaken at the Administrator’s business entity is Konrad Gandziarski, e-mail: Konrad.firstname.lastname@example.org
4. Your personal data will not be conveyed to any third country outside the EU/EEA.
5. Your personal data specified in item 2 above will be stored for the time of the Administrator’s sending commercial or marketing information or until you withdraw your consent for your personal data to be processed for this purpose.
6. In some situations, the Administrator is entitled to convey your personal data to other recipients if it is essential for the purpose of the correct settling of your Award. In such events, we will convey personal data to three groups of recipients: persons authorised by us, our staff and co-operators who must have access to personal data to fulfil their duties, processing entities that we will entrust with personal data processing, and other data recipients, including parcel delivery companies, banks, insurers, and law firms.
7. You are entitled to demand that the Administrator grant you access to personal data which concerns you, as well as correct or remove it, or limit the processing or moving thereof.
8. You are entitled to withdraw your consent at any time by sending a declaration of your withdrawal to the following e-mail address: email@example.com