何时应使用Moq的.As方法? [英] When should I use the .As method of Moq?

查看:104
本文介绍了何时应使用Moq的.As方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到底什么时候需要使用Moq提供的.As方法?

When exactly do we need to use the .As method provided by Moq?

从快速入门文档中:

// implementing multiple interfaces in mock
var foo = new Mock<IFoo>();
var disposableFoo = foo.As<IDisposable>();
// now the IFoo mock also implements IDisposable :)
disposableFoo.Setup(df => df.Dispose());

但是我不明白为什么我们要这么做.你能给我一个实际的例子吗?

But I just don't get why we would want to do that. Could you give me a practical example?

推荐答案

好的,举个例子.假设您有一个运输管理软件来管理汽车,航班等的移动.虽然有不同的车辆,但是它们都是在陆地或空中移动的(没有海上可以简化示例).

Okay, so an example. Let's say you have a transportation management software to manage movement of cars, flights, etc. There are different vehicles but they move on land or air (no sea to simplify the sample).

public interface IMovingOnLand
{
    string Move();
}

public interface IMovingInAir
{
    string Move();
}

还有车辆/飞机的快速运输选择.

And there is an express transport option for a vehicle/aircraft.

public interface IExpressTransport
{
    string MoveDirectly();
}

有一个运输经理班,负责搬运所有车辆/飞机.而且它处理快递运输方式的方式与常规运输方式有所不同(为简单起见,在此示例中,它仅根据是否为IExpressTransport来打印不同的消息):

There is a transport manager class which is responsible for moving all the vehicles/aircraft. And it handles express means of transportation bit differently than regular ones (for the sake of simplicity in this sample it only prints a different message depending whether it's IExpressTransport or not):

public class TransportManager
{
    public string MoveItem(IMovingInAir airCraft)
    {
        if (airCraft is IExpressTransport)
        {
            return "Message from an express aircraft: " +
                ((IExpressTransport)airCraft).MoveDirectly();
        }
        return "Message from an aircraft: " + airCraft.Move();
    }

    public string MoveItem(IMovingOnLand landVehicle)
    {
        if (landVehicle is IExpressTransport)
        {
            return "Message from an express land vehicle: " +
                landVehicle.Move() +
                ((IExpressTransport)landVehicle).MoveDirectly();
        }
        return "Message from a land vehicle: " + landVehicle.Move();
    }
}

现在,您想测试飞机的行为是否不同于汽车.并且,如果常规航班的处理方式与特快航班的处理方式不同.因此,您将对象测试为IMovingInAir对象和IExpressTransport.要仅测试飞行行为,您可以简单地将其创建为Mock<IMovingInAir>.但是要扩展为快速航班,您必须使用As<IExpressTransport>()方法:

Now you would like to test if an airplane behaves differently than a car. And also, if a regular flight is handled differently than an express one. So you test your object as an IMovingInAir object and as IExpressTransport. To test only flight behaviour you can simply create it as Mock<IMovingInAir>. But to extend a flight to an express one you have to use As<IExpressTransport>() method:

[TestMethod]
public void TestTransportManager()
{
    TransportManager manager = new TransportManager();

    // Create a regular flight.
    var flight = new Mock<IMovingInAir>();
    flight.Setup(x => x.Move())
        .Returns("Air craft moved to next stop.");

    // Create a flight.
    var flightExpress = new Mock<IMovingInAir>();
    // Add standard behaviour.
    flightExpress
        .Setup(x => x.Move())
        .Returns("Air craft moved to next stop.");
    // Extend to express and add express flight behaviour.
    flightExpress
        .As<IExpressTransport>()
        .Setup(x => x.MoveDirectly())
        .Returns("Air craft moved directly to destination.");

    // Get the results.
    var res = manager.MoveItem(flight.Object);
    var resExp = manager.MoveItem(flightExpress.Object);

    // Sssert flight and express fligh returned different messages.
    Assert.AreNotEqual(res, resExp);

    // Assert the expected messages have been returned.
    Assert.AreEqual("Message from an aircraft: Air craft moved to next stop.", res);
    Assert.AreEqual("Message from an express aircraft: Air craft moved directly to destination.", resExp);
}

这篇关于何时应使用Moq的.As方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆