I have a service manager class used to abstract my calls from my MVC project to my REST service. All the manager class does is set up the Rest calls (using RestSharp) and return the service data back to the MVC application.

So, at first I thought about not testing such a trivial class, but have decided that tests will safeguard against future changes that might be more complex.

However, here is my dilemma. How far should I abstract things just so that I can test in isolation?

So, I am having my RestClient being injected by MVC into my manager class. I am letting the MVC injector set the base url. All of this I am ok with, but here are the questions I have:

  • For my method call, should I have my method take in a parameter (userId) and an IRestRequest?
    • My problem with this is that all of a sudden my generic servicemanager will become Rest specific as my interface would need to include both parameters.
  • If I do not inject the IRestRequest into the method and let the implementation create it, is this ok since this will be ignored as the main method being tested is the RestClient.Execute, which will be stubbed out and not care about the actual RestRequest?
    • In fact, as this is part of the implementation, I could maybe mock and verify that the Execute method is being sent in the appropriate RestRequest object?
  • Or, should I not inject the IRestRequest, but instead inject an IRequestResolver into my constructor? Then in my methodcall, I can just use the IRequestResolver, which will take in a string representing the method. This will then be used to figure out the RestRequest parameters and return an RestRequest object filled in appropriately for the method?
  • Or, should I just essentially do the sub-bullet under my first bullet, and use the concrete implementation.
  • Any other options I am missing?

I am leaning towards the fourth bullet as it gets to the actual solution being tested?

Let me know if you need any more details to help me resolve my dilemma.

有帮助吗?

解决方案

After discussing this with a friend, I have decided to go with using the concrete implementation.

The reason being that this object is really just a POCO, and there is no need to abstract this out (even though an abstraction is provided). This is my concrete implementation of my service caller, so the actual solution being tested is the call. I will probably mock this out and verify that the restrequest is being called the way it should be, though.

But, the short answer we came up with is that POCO's have no need to be abstracted away.

其他提示

I know this dilemma well; and have been here a few times.

When it comes down to it, you could abstract everything, but you end up with meaningless tests and you find that you're writing test framework that just doesn't matter or you're actually bypassing accepted framework norms in search of the 'one true test methodology'. I have actually been in conversations where people have honestly debated passing abstract interfaces where you'd just need to put an integer.

Whilst writing this I've seen your own answer; and I agree completely.

As long as you can validate assumptions and test behaviour then you're doing enough; like you say - you only need to check that things have changed and you yourself know the boundaries of your own context - Will the provider realistically ever change ? No - don't abstract it.

Recently I've architected some large scale Microsoft Dynamics CRM solutions for my employer; ultimately my tests assume that the CRM API is OK and they just test the behaviour of my wrappers.

Anyway, that's just the ballpark as I see it, I hope this is of some value to you!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top