何时应使用Moq的.As方法? [英] When should I use the .As method of Moq?
问题描述
到底什么时候需要使用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屋!