Moq是静态类中的静态方法

时间:2012-01-29 11:13:37

标签: moq

 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;
    }

以上是我需要编写测试用例的代码片段。 这里LogException(ex);是静态类BusinessExceptionHandler

中的静态方法

我参考了Moq框架工作2.6.1014.1

我如何Moq方法BusinessExceptionHandler.LogException

我更喜欢在方法GetbyID

中不需要任何更改的模拟机制

3 个答案:

答案 0 :(得分:18)

Moq不允许模拟静态方法,因此您可能需要更改静态方法的工作方式。一种选择是让静态方法调用依赖项的实例方法。因此,您将使用Log方法创建“Logger”类,并将静态Logger字段/属性(BusinessExceptionHandler.Logger)添加到静态类。在实际场景中,您可以使用标准Logger实例填充BusinessExceptionHandler.Logger,并将其用作Singleton。为了进行测试,将一个Mock注入到BusinessExceptionHandler.Logger中并设置您的期望并验证模拟。

答案 1 :(得分:8)

Moq(和NMock,RhinoMock)在这里不会帮到你。您必须围绕LogException创建一个包装类(和虚方法),并在生产代码中使用它并使用它进行测试。

如果绝对无法更改现有代码,也可以使用TypeMock,Microsoft.Fakes等工具(http://stacktoheap.com/blog/2012/11/11/testing-extension-methods-with-microsoft-fakes/)。

答案 2 :(得分:1)

以下是我如何解决这个问题。假设这是您要进行单元测试的类:

default void checkTableHasData(Duration atMost, String tableName) throws Exception {
    checkExistsQuery("SELECT COUNT(*) FROM " + tableName),
}

default void checkTableRowExistSearchOnColumn(Duration atMost, String tableName, String columnName,
                                              String columnValue) throws Exception {
    checkExistsQuery("SELECT COUNT(*) FROM " + tableName + " where " + columnName +
                               " = " + columnValue),
}

private static void checkExistsQuery(Duration atMost, String query) {
    try (MysqlQuery mysqlQuery = new MysqlQuery(customersMysqlUrl(host), dbName, user, password)) {

        await().atMost(atMost).pollDelay(Duration.ONE_SECOND).ignoreExceptions().until(
        () -> mysqlQuery.count(query),
        is(Matchers.greaterThan(0)));
    }
}

创建一个接口和一个实现它的包装类:

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

现在嘲笑这个类:

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);
    }
  }

快乐莫青。