【问题标题】:Mock generic, dynamic interface with Moq使用 Moq 模拟通用、动态接口
【发布时间】:2014-03-18 23:03:42
【问题描述】:

我有以下界面可以模拟出来:

internal interface IRenderer
{
    void Render<T>(StringWriter stringWriter, T item) where T : struct;

    void Render(StringWriter stringWriter, decimal item);

    void Render(StringWriter stringWriter, string item);
}

还有一个测试如下:

[Test]
[TestCase("dummy-string", "dummy-string")]
[TestCase(123, "123")]
[TestCase(123.456, "123.456")]
[TestCase(true, "True")]
[TestCase('C', "C")]
public void RendersExpectedValues(dynamic item, string rendered)
{
    // Do some stuff
    using (var stringWriter = new StringWriter(renderedBuilder)
    {
        _mockRenderer.Setup(x => x.Render(textWriter, item));
        _renderer.Render(textWriter, item);
    }

   Assert.It.Worked();
}

如您所见,itemdynamic,过载是在运行时确定的...我玩过

Type type = item.GetType();
_mockRenderer.Setup(x => x.Render<type>(textWriter, item));

Type type = item.GetType();
_mockRenderer.Setup(x => x.Render<typeof(type)>(textWriter, item));

两者都不起作用(当然)。

这可能吗?我可以将字符串测试用例删除到单独的测试中。

【问题讨论】:

    标签: .net dynamic moq


    【解决方案1】:

    我不认为有直接的解决方法——我总是明白:

    错误:表达式树可能不包含动态操作`

    尝试在设置中使用dynamic 时。 AFAIK 您需要对每种支持的类型执行明确的Setup()s。

    但是,您可以稍微干一下,但是使用通用设置辅助方法,例如:

       static class Helpers
       {
          public static Mock<IRenderer> Setup<T>(this Mock<IRenderer> mockRenderer) where T : struct
          {
             mockRenderer.Setup(x => x.Render(It.IsAny<StringWriter>(), It.IsAny<T>()))
                .Callback<StringWriter, T>((sw, s) => sw.Write(s));
             return mockRenderer;
          }
       }
    

    然后可以设置 + 调用:

      [Test]
      [TestCase("dummy-string",  "dummy-string")]
      [TestCase(123, "123")]
      [TestCase(123.456, "123.456")]
      [TestCase(true, "True")]
      public void RendersExpectedValuesString(dynamic item, string rendered)
      {
         var _mockRenderer = new Mock<IRenderer>()
            .Setup<double>()
            .Setup<bool>()
            .Setup<int>()
            .Setup<decimal>();
         _mockRenderer.Setup(x => x.Render(It.IsAny<StringWriter>(), It.IsAny<string>()))
            .Callback<StringWriter, string>((sw, s) => sw.Write(s));
    
         var renderedBuilder = new StringBuilder();
         var sut = new SomethingWhichUsesRenderer(_mockRenderer.Object);
    
          // Do some stuff
          using (var stringWriter = new StringWriter(renderedBuilder))
          {
            sut.DoSomething(stringWriter, item);
    
            // This obviously just tests the Mock ...
            Assert.AreEqual(renderedBuilder.ToString(), rendered);
    
            // Do actual unit tests + Mock.Verifies here
          }
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-28
      • 2011-11-13
      • 1970-01-01
      • 2013-01-16
      • 2018-03-29
      • 1970-01-01
      相关资源
      最近更新 更多