1

I am using Moq for the first time and not really sure on the correct approach for Testing a void returning method I have. I have read this post which was helpful but didnt include many snippets of code for guidance. My method updates my DB with responses from an external webservice for a list of my car objects

My method is as below:

    public void UpdateDBWithWebResponse(Response response, List<Car> cars)
    {
        try
        {
            if (response == null)
            {
        //Exception logged
            }
            foreach (var webResponse in response.Responses)
            {
                var car = cars.First(c => c.Id == webResponse.Id);

                if (response.detailResponse == null || response.detailResponse.Values == null)
                {
                   //Exception logged
                }

                foreach (var detailResponse in response.HazardResponse.Values)
                {
                    UpdateDetailResponseOnCar(detailResponse, car);
                }                 
            }
    //update the DB
            _carRepository.Update(cars);

        }
        catch (Exception ex)
        {
           //log error
        }
    }

So it takes two parameters a Web response object and a list of car objects - UpdateDetailResponseOnCar(detailResponse, car); is a private method which maps the web reponse to the car object and then the data is saved to the DB.

I guess what I want to Test is that if the response is null then an exception is called? Similariy with the inner detail response if null is exception thrown. And then if I create a Mock response object and a mock list of cars I want to save that to a Test instance of my DB and assert that the correct values were mapped?

Does this seem like a good strategy to test the above method and has anyone got any code snippets for testing the null response throws exception and for the other cases?

Community
  • 1
  • 1
Ctrl_Alt_Defeat
  • 3,933
  • 12
  • 66
  • 116
  • 1
    First, don't put a try catch around everything in your method. Best to catch only specific errors that you expect out of the dependencies. – Daniel Robinson Jun 02 '14 at 15:17
  • Remove Response from UpdateDb method. Keep things separate. 1 method should receive something from web service, validate response and return a list of some model objects (simple class instances). UpdateDb method then gets nice detached data and it only responsibility is then to update DB (and not also validate web service response). – pero Jun 02 '14 at 15:22
  • What have you tried? Moq is about creating fake objects which deliver test data when called. It sounds likk what you want is to be able to unit test a call to this function where "reponse" is null. In that case just setup a unit test with an ExpectedException (I'm assuming you're using NMock or MSTest), make this call and assert that you do get your exception thrown. – Kevin Roche Jun 02 '14 at 15:22
  • By "Exception logged", do you mean that an exception is thrown or a message is logged with some logging library? – Meta-Knight Jun 02 '14 at 15:30
  • Message is logged but an application exception is also thrown – Ctrl_Alt_Defeat Jun 02 '14 at 15:44

2 Answers2

1

First, remove the catch around everything.

Ideally you would throw exceptions where absolutely necessary, and then allow the calling code to catch them.

That way you can catch the exception in your test.

Perhaps best to use specific exceptions, e.g. ArgumentNullException for the case when response is null.

See the following for MSTest: http://www.contentedcoder.com/2012/01/asserting-exceptions-in-mstest-with.html

Daniel Robinson
  • 2,165
  • 17
  • 14
0

What testing framework are you using? If you're using something like NUnit, you can add the ExpectedException attribute. That works if the exception is uncaught. So in your UpdateDBWithWebResponse method, you could log and rethrow it perhaps.

Dan Csharpster
  • 2,662
  • 1
  • 26
  • 50
  • I am using Moq and MS Test – Ctrl_Alt_Defeat Jun 02 '14 at 15:23
  • That has ExpectedException as well: [TestMethod()] [ExpectedException(typeof(System.DivideByZeroException))] public void DivideTest() http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.expectedexceptionattribute.aspx – Dan Csharpster Jun 02 '14 at 16:04