单行多属性代码的Moq

时间:2017-04-04 15:21:04

标签: c# moq

我有这些接口

public interface Interface1 { Interface2 Items {get;} }
public interface Interface2 { Guid? ApplicationTypeId { get; } }
public interface Interface3 { Class1 Item {get;} }
public interface Interface4 { Guid? ApplicationId { get; set; } }

一个类继承了第一个接口

public class Class1 : Interface1 {
   public Interface2 Items { get; }
}

另一个由几个guid组成的课程

public static class ContentTypeIds
{
    public static Guid ContentGuid1 => new Guid("{11798e9d-a167-4cfc-8cfa-9a24fd6caf25}");

    public static Guid ContentGuid2 => new Guid("{7d22f5bb-37fd-445a-b322-2fa1b108d260}");
}

我需要对以下属性进行单元测试

private readonly Interface3 _interface3;
public Ticket Current
{
   get
   {
      //This line is very complicated
      Interface4 itemByContentType = _interface3.Item?.Items.GetItemByContentType(ContentTypeIds.ContentGuid2);
      if ( itemByContentType?.ContentId != null )
          return Get(itemByContentType.ContentId.Value);
      return null;
   }
}

我的测试课程就在这里

[Test]
public class TestClass {
    var mock1 = new Mock<Interface1>();
    var mock2 = new Mock<Interface2>();
    var mock3 = new Mock<Interface3>();

    mock1.SetupAllProperties();
    mock2.SetupAllProperties();
    mock3.SetupAllProperties();
}

'itemByContentType'的值为null。 任何人都可以帮我把它变得简单和可测试,因为测试这个属性变得复杂了吗?我正在使用Moq。我将不胜感激。

由于

1 个答案:

答案 0 :(得分:0)

我不是Moq的专家,但看起来它的 SetupAllProperties 方法只是将所有属性设置为属性(即它创建的对象具有可以支持GET的持久成员/ SET操作)。如果没有这样做,那么据我所知,属性仍然可用,但它们将始终解析为<​​em> null 。这在准备Mock对象时非常方便,但是它本身并没有设置具有任何值的属性。

我认为你应该做的是使用Moq的 SetupGet 返回方法来准备具有特定值的Items属性的GET。

以下是一些(简化的)示例代码,用于演示:

public interface IFoo { Guid? ApplicationId { get; set; } }
public interface IBar { IFoo Items { get; } }

class Program
{

    static void Main(string[] args)
    {
        // SETUP
        // Prepare mocks
        Mock<IFoo> MockFoo = new Mock<IFoo>();
        Mock<IBar> MockBar = new Mock<IBar>();

        // Seting up properties allows us read/write Foo's ApplicationId
        MockFoo.SetupAllProperties();

        // The mocked Foo object should be what's returned when Items is requested
        var expectedFoo = MockFoo.Object;

        // Setup the Bar object to return that mocked Foo
        MockBar.SetupGet(x => x.Items).Returns(expectedFoo);

        // The value written here will be persistent due to SetupAllProperties
        expectedFoo.ApplicationId = new Guid("{7d22f5bb-37fd-445a-b322-2fa1b108d260}");




        // ACTION
        // When the "Items" property is accessed, the IFoo we get should be what we mocked...
        var actualFoo = MockBar.Object.Items;

        // ... and we can read the value set to Foo's ApplicationId
        var actualAppId = actualFoo.ApplicationId;
    }
}