Azure-iot-sdk-csharp: Make `DeviceClient` mockable

Created on 17 May 2017  路  4Comments  路  Source: Azure/azure-iot-sdk-csharp

Could we please have DeviceClient implement an interface called IDeviceClient so it's mockable for unit testing purposes in downstream projects? Thanks!

enhancement

Most helpful comment

@CIPop it is controversial if "Only Mock Types That You Own" is a Code smell, see Stack Overflow: Should you only mock types you own?

I have have a azure function which is currently written in Node, but since Node Function have no Claims Support (https://github.com/Azure/azure-functions-nodejs-worker/pull/183) I considered, to move this code to c#. But with adding extra wrapper would blow this little function (39 loc and two method calls to the iothub library) disproportionately.

So please reconsider and let the user of the Library decide if they want to mock types they not own.

All 4 comments

Personally, I use own wrapper of DeviceClient for mocking in my project. It is great if DeviceClient become mockable!

Regardless of the language, the described problem is a code smell in your application's design. See chapter 8 of Growing Object-Oriented Software, Guided by Tests for reasons to "Only Mock Types That You Own".

Larger SDKs (e.g. .NET Framework) are not providing public interfaces unless those interfaces (a) will never change and (b) must be implemented by application code to achieve certain behaviors (e.g. IDisposable).
Adding such an interface will work only in the version that it is added. Once we add another member to DeviceClient, to respect our binary compatibility promise the IDeviceClient will remain the same and you won't be able to mock new functionality. (We won't consider adding a new interface for each new public API.)

@yfakariya's answer is the correct one: create your own wrapper (facade or adapter). I would also recommend a factory method/class together with the wrapper. That way:

  • You know exactly what functionality your application uses from the type
  • You can adapt in case of undesired changes in behavior
  • You can easily mock

Here are a few online resources:
http://tech.findmypast.com/dont-mock-what-you-dont-own/
https://8thlight.com/blog/eric-smith/2011/10/27/thats-not-yours.html

@CIPop it is controversial if "Only Mock Types That You Own" is a Code smell, see Stack Overflow: Should you only mock types you own?

I have have a azure function which is currently written in Node, but since Node Function have no Claims Support (https://github.com/Azure/azure-functions-nodejs-worker/pull/183) I considered, to move this code to c#. But with adding extra wrapper would blow this little function (39 loc and two method calls to the iothub library) disproportionately.

So please reconsider and let the user of the Library decide if they want to mock types they not own.

It seems to me that creating a wrapper for the sole purpose of unit testing is more of a code smell than mocking an object you don't own.

Was this page helpful?
0 / 5 - 0 ratings