存根或模拟IMapper返回基数预期的派生类

时间:2017-12-02 19:14:50

标签: unit-testing mocking automapper moq stub

我有一个类在构造函数中接受IMapper,如此

public Foo(IMapper mapper)

在Foo的代码中我有这一行

var dao = _mapper.Map<BaseDAO>(obj);

BaseDAO有3个子类型,在我设置的实际代码中

CreateMap<Base, BaseDAO>()
     .Include<Child1, Child1DAO>()
     .Include<Child2, Child2DAO>()
     .Include<Child3, Child3DAO>();

我想嘲笑上面一行

var dao = _mapper.Map<BaseDAO>(obj);

因此,如果传入Child1,则返回Child1DAO,其他子类型也相同。我试图删除IMapper,但以下方法返回错误说

  

Child1DAO无法隐式转换为TDestination

我尝试模仿IMapper,但无法使其工作。

public TDestination Map<TDestination>(object source)
{
    return new Child1DAO();
}

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

出于本示例的目的,假设以下类是测试对象

public class Foo {
    private IMapper mapper;
    public Foo(IMapper mapper) {
        this.mapper = mapper;
    }

    public BaseDAO Bar(object obj) {
        var dao = mapper.Map<BaseDAO>(obj);
        return dao;
    }
}

IMapper依赖关系定义了以下合同

public interface IMapper {
    /// <summary>
    /// Execute a mapping from the source object to a new destination object.
    /// The source type is inferred from the source object.
    /// </summary>
    /// <typeparam name="TDestination">Destination type to create</typeparam>
    /// <param name="source">Source object to map from</param>
    /// <returns>Mapped destination object</returns>
    TDestination Map<TDestination>(object source);

    //...
}

以下测试使用moq演示

  

模拟IMapper返回预期基数的派生类

[TestClass]
public class TestClass {
    [TestMethod]
    public void _TestMethod() {
        //Arrange
        var mock = new Mock<IMapper>();
        var foo = new Foo(mock.Object);

        mock
            //setup the mocked function
            .Setup(_ => _.Map<BaseDAO>(It.IsAny<object>()))
            //fake/stub what mocked function should return given provided arg
            .Returns((object arg) => {
                if (arg != null && arg is Child1)
                    return new Child1DAO();
                if (arg != null && arg is Child2)
                    return new Child2DAO();
                if (arg != null && arg is Child3)
                    return new Child3DAO();

                return null;
            });

        var child1 = new Child1();

        //Act
        var actual = foo.Bar(child1);

        //Assert
        Assert.IsNotNull(actual);
        Assert.IsInstanceOfType(actual, typeof(BaseDAO));
        Assert.IsInstanceOfType(actual, typeof(Child1DAO));
    }
}
相关问题