18
 public Product GetbyID(int id)
    {            
            try
            {
               //mycode Product p=..........

            }
            catch (DataAccessException ex)
            {
                throw new BusinessException(ex.ErrorCode);
            }
            catch (Exception ex)
            {
                BusinessExceptionHandler.LogException(ex);
            }

        return p;
    }

Given above is a code snippet that i need to write test cases. here LogException(ex); is a static method in static class BusinessExceptionHandler

I have reference to Moq frame work 2.6.1014.1

How can I Moq the method BusinessExceptionHandler.LogException

I do prefer a mocking mechanism that don't need any change in method GetbyID

BlackWasp
  • 4,933
  • 2
  • 30
  • 42
Kuttan Sujith
  • 7,889
  • 18
  • 64
  • 95

3 Answers3

19

Moq doesn't allow the mocking of static methods so you will probably need to change the working of the static method. One option is to have the static method call an instance method of a dependency. So you'll create a "Logger" class with a Log method and add a static Logger field / property (BusinessExceptionHandler.Logger) to your static class. In the real-world scenario you can populate BusinessExceptionHandler.Logger with a standard Logger instance, using it as a Singleton. For testing, inject a Mock into the BusinessExceptionHandler.Logger and set up your expectations and verify against the mock.

BlackWasp
  • 4,933
  • 2
  • 30
  • 42
11

Moq (and NMock, RhinoMock) will not help you here. You will have to create a wrapper class ( and virtual method ) around the LogException and use it in production code and test using that.

Or you can use a tool like TypeMock, Microsoft.Fakes etc ( http://stacktoheap.com/blog/2012/11/11/testing-extension-methods-with-microsoft-fakes/ ) if you absolutely cannot change your existing code.

manojlds
  • 290,304
  • 63
  • 469
  • 417
8

Here is how I get around the problem. Say this is the class you want to unit-test:

 public static class TaskFactory
 {
   public static T CreateTask<T>(long workRequestId, ProcessTriggerType workRequestType)
   {
     var task = some code to do the work;
     return (T)task;
   }
 }

Create an interface and a wrapper class implementing it:

public interface ITaskFactoryFacade
  {
    T CreateTask<T>(long workRequestId, ProcessTriggerType workRequestType);
  }

  public class TaskFactoryFacade : ITaskFactoryFacade
  {
    public T CreateTask<T>(long workRequestId, ProcessTriggerType workRequestType)
    {
      return TaskFactory.CreateTask<T>(workRequestId, workRequestType);
    }
  }

Now mock out this class:

var taskFactoryFacadeMock = new Mock<ITaskFactoryFacade>();
taskFactoryFacadeMock.Setup(t => t.CreateTask<SomeTask>(It.IsAny<long>(), It.IsAny<SomeType>())).Returns(new SomeTask());

Happy Moqing.

MonteChristo
  • 589
  • 6
  • 11
  • Okay, but by doing this you have to change the class and method from static to non-static. What about NOT changing the original method? What can you do in that case? Static classes cannot implement interfaces. – carloswm85 Oct 18 '22 at 15:42