为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用Moq模拟扩展方法?

如何使用Moq模拟扩展方法?

C#
PIPIONE 2019-07-30 16:51:05
如何使用Moq模拟扩展方法?我正在编写一个依赖于扩展方法结果的测试,但我不希望该扩展方法的未来失败会破坏此测试。模拟这个结果似乎是显而易见的选择,但是Moq似乎没有提供一种覆盖静态方法的方法(扩展方法的要求)。与Moq.Protected和Moq.Stub有类似的想法,但它们似乎没有为这种情况提供任何东西。我错过了什么或者我应该以不同的方式去做这件事吗?这是一个简单的例子,通常会对“不可覆盖的成员的无效期望”失败。这是需要模拟扩展方法的一个不好的例子,但它应该这样做。public class SomeType {     int Id { get; set; }}var ListMock = new Mock<List<SomeType>>();ListMock.Expect(l => l.FirstOrDefault(st => st.Id == 5))         .Returns(new SomeType { Id = 5 });至于任何可能暗示我使用Isolator的TypeMock迷们:我很欣赏这项努力,因为看起来TypeMock可以完成蒙住眼睛和醉酒的工作,但我们的预算不会很快增加。
查看完整描述

3 回答

?
白衣非少年

TA贡献1155条经验 获得超0个赞

扩展方法只是伪装的静态方法。像Moq或Rhinomocks这样的模拟框架只能创建对象的模拟实例,这意味着无法模拟静态方法。


查看完整回答
反对 回复 2019-07-30
?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

如果您可以更改扩展方法代码,那么您可以像这样编码以便能够测试:

using System;using Microsoft.VisualStudio.TestTools.UnitTesting;using Moq;public static class MyExtensions{
    public static IMyImplementation Implementation = new MyImplementation();

    public static string MyMethod(this object obj)
    {
        return Implementation.MyMethod(obj);
    }}public interface IMyImplementation{
    string MyMethod(object obj);}public class MyImplementation : IMyImplementation{
    public string MyMethod(object obj)
    {
        return "Hello World!";
    }}

因此,扩展方法只是实现接口的包装。

(你可以只使用没有扩展方法的实现类,这些扩展方法是一种语法糖。)

您可以模拟实现接口并将其设置为扩展类的实现。

public class MyClassUsingExtensions{
    public string ReturnStringForObject(object obj)
    {
        return obj.MyMethod();
    }}[TestClass]public class MyTests{
    [TestMethod]
    public void MyTest()
    {
        // Given:
        //-------
        var mockMyImplementation = new Mock<IMyImplementation>();

        MyExtensions.Implementation = mockMyImplementation.Object;

        var myObject = new Object();
        var myClassUsingExtensions = new MyClassUsingExtensions();

        // When:
        //-------
        myClassUsingExtensions.ReturnStringForObject(myObject);

        //Then:
        //-------
        // This would fail because you cannot test for the extension method
        //mockMyImplementation.Verify(m => m.MyMethod());

        // This is success because you test for the mocked implementation interface
        mockMyImplementation.Verify(m => m.MyMethod(myObject));
    }}


查看完整回答
反对 回复 2019-07-30
  • 3 回答
  • 0 关注
  • 538 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信