使用Moq和Autofac进行单元测试

用户名

我有以下logger logger类,并且我想知道最好的对它进行单元测试的内容。

一些观察:

  1. 我需要创建接口IFileWrapper以便打破与System.IO依赖关系的依赖关系,并能够进行用户依赖关系注入(Autofac)
  2. 我可以通过使用MemoryString实现IFileWrapper来对FileWrapper.WriteLog方法进行单元测试,但是如果我想测试该方法内部的预期行为(例如:抛出异常,错误的路径和文件名等),

    /// <summary>
    /// Creates an instance of type <see cref="FileLogger"/>
    /// </summary>
    /// <remarks>Implements the Singleton Pattern</remarks>
    private FileLogger()
    {
        FileName = string.Format("\\{0: MMM dd, yy}.log", DateTime.Now);
        Path = Environment.CurrentDirectory;
    
        FileWrapper = ContainerBuilderFactory.Container.Resolve<IFileWrapper>();
    }
    
    /// <summary>
    /// Log the <paramref name="Message"/> in the <paramref name="Path"/> specified.
    /// The <paramref name="UserName"/>, <paramref name="Host"/> must be supplied
    /// </summary>
    /// <example>
    ///     <code>
    ///         var handler = new LoggerHandlerFactory();
    ///         var logger = handler.GetHandler<FileLogger>();
    ///         logger.Log("Hello CSharpLogger");
    ///     </code>
    /// </example>
    /// <exception cref="ArgumentNullException"></exception>
    /// <exception cref="ArgumentException"></exception>
    /// <exception cref="NotSupportedException"></exception>
    /// <exception cref="FileNotFoundException"></exception>
    /// <exception cref="IOException"></exception>
    /// <exception cref="SecurityException"></exception>
    /// <exception cref="DirectoryNotFoundException"></exception>
    /// <exception cref="UnauthorizedAccessException"></exception>
    /// <exception cref="PathTooLongException"></exception>
    /// <exception cref="ArgumentOutOfRangeException"></exception>
    /// <exception cref="FormatException"></exception>
    public void Log(string message, LogLevel level = LogLevel.INFO)
    {
        lock (_current)
        {
            var configLevel = CSharpLoggerConfiguration.Configuration.GetLogLevel();
    
            if (configLevel != LogLevel.OFF & level != LogLevel.OFF && configLevel >= level)
            {
                try
                {
                    FileWrapper.WriteLog(string.Concat(Path, FileName), message, level);
                }
                catch (CSharpLoggerException)
                {
                    throw;
                }
            }
        }
    }
    

因此,我使用Moq创建了以下UnitTesting:

 //arrange
        CSharpLoggerConfiguration.Configuration.SetLogLevel(LogLevel.DEBUG);

        var mock = new Mock<IFileWrapper>();
        mock.Setup(x => x.WriteLog(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<LogLevel>()));

        logger.FileWrapper = mock.Object;

        //act
        logger.Log("Hello CSharpLogger", LogLevel.DEBUG);
        logger.Log("Hello CSharpLogger", LogLevel.WARN);

        //assert 
        mock.Verify(x => x.WriteLog(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<LogLevel>()), Times.Exactly(2));

到现在为止还挺好。我不满意的是这一行:logger.FileWrapper = mock.Object; 我想保留FileWrapper的私有属性。

任何建议都欢迎。

如果您需要更多详细信息,我将发布代码http://csharplogger.codeplex.com/

托马斯·阿尚(Tomas Aschan)

使用构造函数注入简而言之; 而不是通过设置属性来提供服务(在本例中为文件包装器),而是使记录器具有一个带IFileWrapper参数的公共构造函数。

public class Logger
{
    public Logger(IFileWrapper fileWrapper)
    {
        FileWrapper = fileWrapper;
    }

    public IFileWrapper FileWrapper { get; }
}

// in your test:
var logger = new Logger(mock.Object);

为了更彻底地回答有关单例文件包装的问题,这是应用程序(非测试)代码的代码示例:

public static class FileWrapperFactory
{
    private static IFileWrapper _fileWrapper;

    public static IFileWrapper GetInstance()
    {
        return _fileWrapper ?? (_fileWrapper = CreateInstance());
    }

    private static IFileWrapper CreateInstance()
    {
        // do all the necessary setup here
        return new FileWrapper();
    }
}


public class StuffDoer
{
    public void DoStuff()
    {
        var logger = new FileLogger(FileWrapperFactory.GetInstance());

        logger.WriteLog("Starting to do stuff...");

        // do stuff

        logger.WriteLog("Stuff was done.");
    }
}

由于FileWrapperFactory维护文件包装器的静态实例,因此您永远不会拥有一个以上的实例。但是,您可以像这样创建多个记录器,而不必在意。如果将来您决定可以有许多文件包装器,则记录器代码不必更改。

建议您在实际应用中选择某种DI框架来为您处理所有记账工作。大多数都对单例实例提供了出色的支持,基本上可以完成FileWrapperFactory上述操作(但是通常以更复杂,更健壮的方式进行。FileWrapperFactory例如,不是线程安全的...)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用 Moq 和接口进行单元测试

来自分类Dev

使用Moq进行单元测试

来自分类Dev

使用 Moq 框架进行单元测试

来自分类Dev

使用Moq进行单元测试的通用工作单元和存储库模式框架

来自分类Dev

使用Moq进行单元测试的工作单元和通用存储库模式框架

来自分类Dev

EF通用存储库和工作单元-使用Moq进行单元测试

来自分类Dev

Moq和EF6进行单元测试

来自分类Dev

在使用Moq和AutoFixture进行单元测试API时模拟HttpResponseMessage

来自分类Dev

使用XUnit和MOQ进行单元测试OData V4 PUT操作

来自分类Dev

使用 xunit 和 moq 进行 net core api 控制器单元测试

来自分类Dev

使用moq模拟HttpContext进行单元测试

来自分类Dev

使用Moq进行单元测试,但对象返回Null

来自分类Dev

使用Moq对dbContext进行单元测试添加操作

来自分类Dev

moq进行单元测试的通用方法

来自分类Dev

单元测试-如何使用MOQ进行MOQ WCF客户端

来自分类Dev

使用Moq的单元测试cosmosDb方法

来自分类Dev

使用Moq安排单元测试

来自分类Dev

模仿ViewModel进行Moq进行单元测试?

来自分类Dev

如何对使用Scanner和InputStream的方法进行单元测试?

来自分类Dev

首次使用Mocha和Sinonjs进行异步单元测试

来自分类Dev

使用$ parsers(和$ formatters)对指令进行单元测试

来自分类Dev

使用Rspec和C扩展进行单元测试

来自分类Dev

使用MVC API和Ninject进行单元测试

来自分类Dev

使用Android Studio和Gradle进行单元测试?

来自分类Dev

使用Laravel assertDatabaseHas和浮点列进行单元测试

来自分类Dev

使用Android Studio和Gradle进行单元测试?

来自分类Dev

节点,使用sinon进行单元测试和模拟

来自分类Dev

使用Rspec和C扩展进行单元测试

来自分类Dev

使用$ httpbackend模拟和打字稿进行单元测试

Related 相关文章

  1. 1

    使用 Moq 和接口进行单元测试

  2. 2

    使用Moq进行单元测试

  3. 3

    使用 Moq 框架进行单元测试

  4. 4

    使用Moq进行单元测试的通用工作单元和存储库模式框架

  5. 5

    使用Moq进行单元测试的工作单元和通用存储库模式框架

  6. 6

    EF通用存储库和工作单元-使用Moq进行单元测试

  7. 7

    Moq和EF6进行单元测试

  8. 8

    在使用Moq和AutoFixture进行单元测试API时模拟HttpResponseMessage

  9. 9

    使用XUnit和MOQ进行单元测试OData V4 PUT操作

  10. 10

    使用 xunit 和 moq 进行 net core api 控制器单元测试

  11. 11

    使用moq模拟HttpContext进行单元测试

  12. 12

    使用Moq进行单元测试,但对象返回Null

  13. 13

    使用Moq对dbContext进行单元测试添加操作

  14. 14

    moq进行单元测试的通用方法

  15. 15

    单元测试-如何使用MOQ进行MOQ WCF客户端

  16. 16

    使用Moq的单元测试cosmosDb方法

  17. 17

    使用Moq安排单元测试

  18. 18

    模仿ViewModel进行Moq进行单元测试?

  19. 19

    如何对使用Scanner和InputStream的方法进行单元测试?

  20. 20

    首次使用Mocha和Sinonjs进行异步单元测试

  21. 21

    使用$ parsers(和$ formatters)对指令进行单元测试

  22. 22

    使用Rspec和C扩展进行单元测试

  23. 23

    使用MVC API和Ninject进行单元测试

  24. 24

    使用Android Studio和Gradle进行单元测试?

  25. 25

    使用Laravel assertDatabaseHas和浮点列进行单元测试

  26. 26

    使用Android Studio和Gradle进行单元测试?

  27. 27

    节点,使用sinon进行单元测试和模拟

  28. 28

    使用Rspec和C扩展进行单元测试

  29. 29

    使用$ httpbackend模拟和打字稿进行单元测试

热门标签

归档