匹配器
匹配器允许您忽略将实际值作为mock中使用的参数传递。相反,它们让您可以只传递满足参数类型或期望值范围的表达式。例如,如果一个方法接受一个字符串作为第一个参数,你不需要传递一个特定的字符串,如“Camera”。相反,您可以使用参数。IsAny
在TelerikJustMock中支持几种类型的匹配器:
- 已定义的匹配器(
参数。AnyBool
,参数。AnyDouble
,参数。AnyFloat
,参数。AnyGuid
,参数。AnyInt
,参数。AnyLong
,参数。AnyObject
,参数。AnyShort
,参数。AnyString
,参数。NullOrEmpty
) Arg.IsAny T < > ();
参数。IsInRange (
[FromValue: int], [ToValue: int], [RangeKind])
参数。谓词匹配< T >(表达< < T > >表达式)
Arg.Ref ()
匹配器还允许您通过一个调用来忽略mock中的所有参数IgnoreArguments ()
(在安排中)或Args.Ignore ()
(断言中)。
为了详细了解这些特性,我们将使用以下接口:
公共接口IFoo {int Echo(int intArg1);int Echo(int intArg1, int intArg2);int Bar(ref int intArg1);}
公共接口IFoo Function Echo(ByVal int As Integer) As Integer Function Echo(ByVal int1 As Integer, ByVal int As Integer) As Integer Function Bar(ByRef int1 As Integer) As Integer结束接口
公共接口IPaymentService {void ProcessPayment(DateTime dateTi,十进制十进制);}
Public接口IPaymentService子进程支付(ByVal dateTi As DateTime, ByVal deci As Decimal)结束接口
参数。IsAny
();
我们已经在前面的示例中使用了这个匹配器。
Mock.Arrange(() => warehouse.HasInventory(Arg.IsAny(), Arg.IsAny())).Returns(true);
() warehouse.HasInventory (Arg Mock.Arrange(函数。IsAny(Of String)(),参数。IsAny(Of Integer)())).Returns(True)
这个匹配器指定当HasInventory方法调用时,第一个参数是字符串,第二个参数是int真正的.
参数。IsInRange(int from, int to, RangeKind range)
IsInRange匹配器允许我们安排一个期望值范围的调用。与RangeKind参数时,我们可以指定给定范围是否包含或不包含其边界。考虑下面的例子:
Mock.Arrange(() => foo.Echo(参数。IsInRange (0, 5, RangeKind.Inclusive))).Returns(true);
() foo.Echo (Arg Mock.Arrange(函数。IsInRange (0, 5, RangeKind.Inclusive))).Returns(True)
在第一行中,我们指定foo。回声方法时,参数值从0到5不等,则该方法将返回真正的.我们指定RangeKind包含,这意味着调用0或5的方法满足范围条件,它将返回真正的对于这些值。
Mock.Arrange(() => foo.Echo(参数。IsInRange (0, 5, RangeKind.Exclusive))).Returns(true);
() foo.Echo (Arg Mock.Arrange(函数。IsInRange (0, 5, RangeKind.Exclusive))).Returns(True)
在第二行中,我们指定RangeKind是独家因此,使用6或10调用方法并不满足条件,因为这些值被排除在范围之外。
参数。匹配
(表达式
>表达式)
这是最灵活的匹配器,它允许您指定自己的匹配表达式。让我们用一个简单的例子来说明:
Mock.Arrange(() => foo.Echo(参数。匹配( x => x < 10)).Returns(true);
() foo.Echo (Arg Mock.Arrange(函数。匹配(Of Integer)(Function(x) x < 10))).Returns(True)
用我们的表达式(或谓词)X => X < 10我们指定一个调用foo。回声参数小于10时返回真正的.
忽略排列中的所有参数
要对某种方法设定独立的期望,你必须应用IgnoreArguments
对它的安排。下一个例子演示了这个功能:
[TestMethod] public void ignoringallargumentsforaspecificexpect () {// Arrange var foo = Mock.Create();Mock.Arrange(() => foo。回声(0, 0)).IgnoreArguments().Returns(10); // Act int actual = foo.Echo(10, 200); // Assert Assert.AreEqual(10, actual); }
Public Sub ignoringallargumentsforaspecificexpect () '安排Dim foo = Mock。Create(Of IFoo)() Mock.Arrange(Function() foo. foo.)Echo(0,0)).IgnoreArguments().Returns(10) '将Dim actual As Integer = foo。Echo(10,200) '维护维护。AreEqual(10, actual)结束Sub
的模拟创建后IFoo
我们每天都安排回声
调用,不管它的参数都应该返回10。为此,在排列中传递来自其对应类型的参数,然后应用IgnoreArguments
功能。
在Assert中使用匹配器
匹配器在断言中也很有用。考虑一个虚构的支付服务,我们不关心支付日期,但我们希望确保传递给该服务的支付金额为54.44美元。我们可以通过使用下面的语句轻松实现这一点:
[TestMethod] public void ShouldUseMatchersInAssert() {// Arrange var paymentService = Mock.Create();// Act paymentService.ProcessPayment(日期时间。现在,54.44米);// Assert Mock.Assert(() => paymentService. bat。processspayment (Arg. isany (), Arg. isany ())匹配(paymentAmount => paymentAmount == 54.44M))); }
公共子ShouldUseMatchersInAssert() '安排Dim paymentService = Mock。Create(Of IPaymentService)()行动paymentService.ProcessPayment (DateTime。现在,54.44D) 'Assert(Sub() paymentService。ProcessPayment(参数。IsAny(Of DateTime)(), Arg.Matches(Of Decimal)(Function(paymentAmount) paymentAmount = 54.44D))) End Sub
我们断言ProcessPayment
与任何DateTime
参数和支付金额准确54.44美元
.
这里还有一个例子。我们指定回声
带参数调用10
而且20.
应该返回30.
.我们使用匹配器参数。匹配
而且参数。匹配
等我们过去了再处理这个案子10
而且20.
到回声
方法。
[TestMethod] public void ShouldUseMatchersInArrange() {// Arrange var foo = Mock.Create();Mock.Arrange(() => foo.Echo(参数。匹配(x => x == 10),匹配(x => x == 20))).Returns(30); // Act int ret = foo.Echo(10, 20); // Assert Assert.AreEqual(30, ret); }
公共子ShouldUseMatchersInArrange() '安排Dim foo = Mock。Create(Of IFoo)() Mock.Arrange(Function() foo.Echo(Arg. echo)匹配(整数)(函数(x) x = 10),参数。匹配(Of Integer)(Function(x) x = 20))).Returns(30) ' Act Dim ret As Integer = foo.Echo(10, 20) ' Assert Assert.AreEqual(30, ret) End Sub
使用匹配器忽略Assert中的所有参数
您已经看到了如何在断言调用中使用匹配器。如果需要,可以指定忽略assert调用中的所有参数。你可以通过添加Args.Ignore ()
的参数模拟。断言
调用。这里有一个例子:
[TestMethod] public void UsingMatchersInAssertExample2(){//安排var paymentService = Mock.Create();// Act paymentService.ProcessPayment(日期时间。现在,54.44米);// Assert Mock.Assert(() => paymentService. bat。ProcessPayment(new DateTime(), 0), Args.Ignore()); }
公共子ShouldIgnoreArgumentsInAssert() '安排Dim paymentService = Mock。Create(Of IPaymentService)()行动paymentService.ProcessPayment (DateTime。现在,54.44D) 'Assert(Sub() paymentService。ProcessPayment(New DateTime(), 0), Args.Ignore()) End Sub
以这种方式,我们主张召唤ProcessPayment
不管有什么争论。
使用匹配器和特化
在一个安排中,你可以定义多个匹配器。考虑下面的例子:
[TestMethod] [ExpectedException(typeof(ArgumentException))] public void UsingMatchersAndSpecializations() {// Arrange var foo = Mock.Create();Mock.Arrange(() => foo.Echo(Arg.AnyInt)) .Returns(10) .OccursOnce();Mock.Arrange(() => foo.Echo(参数。匹配(x => x > 10))).Throws(new ArgumentException()); // Act int actual = foo.Echo(1); // Assert Assert.AreEqual(10, actual); // Act foo.Echo(11); }
_ _ Public Sub ShouldUseMatchersAndSpecializations() '安排Dim foo = Mock。Create(Of IFoo)() Mock.Arrange(Function() foo.Echo(Arg. anyint)). returns (10) Mock.Arrange(Function() foo.Echo(Arg. anyint)).匹配(整数)(函数(x) x > 10)))。抛出(New ArgumentException()) 'Act Dim actual As Integer = foo.Echo(1) '维护维护。AreEqual(10, actual) '表演foo.Echo(11)结束
在与之间使用专门化的情况下参数。IsAny < T >
, JustMock将使用适当的匹配器选择排列。foo.Echo (1)
将使用第一个匹配器并返回10
.但foo.Echo (11)
将使用第二个匹配器,因为它是第一个匹配器的专门化,因此应用调用ArgumentException
会被扔。
为ref参数使用匹配器(args . ref ())
参数。裁判
仅用于c#程序集,至于Visual Basic你可以直接匹配吗ByRef
没有它的论点。
使用JustMock,您可以为接受ref参数的函数使用匹配器。为此,您需要使用Arg.Ref () value
语法。查看下面的例子以获得进一步指导:
这里我们将使用
参数。裁判
Matcher,以匹配将被调用的ref参数为已知的函数价值.[TestMethod] public void matchingcerrefparameters () {int myrefag = 5;//排列变量foo = Mock.Create
();Mock.Arrange(() => foo。栏(ref Arg.Ref (5) value) .Returns (10);// Act int actual = foo。酒吧(ref myRefArg);// Assert。AreEqual(10、实际);断言。myRefArg AreEqual(5日);} Public Sub matchingsurerefparameters () Dim myRefArg As Integer = 5 '排列Dim foo = Mock。Create(Of IFoo)() Mock.Arrange(Function() foo.Bar(5)).Returns(10) '作为整数= foo.Bar(myRefArg) '维护维护。AreEqual(10, actual)断言。AreEqual(5, myRefArg)结束Sub 注意,的使用价值字段在匹配器的末尾(
Arg.Ref (5)
value)是使用此特性所需要的。这里我们将使用
参数。裁判
Matcher,以匹配将被调用的ref参数为已知的函数类型.为了匹配类型,我们将使用一个已定义的匹配器。[TestMethod] public void MatchingRefParametersOfAnyType() {int myRefArg = 5;//排列变量foo = Mock.Create
();Mock.Arrange(() => foo。酒吧(ref Arg.Ref(参数。AnyInt).价值)).Returns(10); // Act int actual = foo.Bar(ref myRefArg); // Assert Assert.AreEqual(10, actual); Assert.AreEqual(5, myRefArg); } Public Sub MatchingRefParametersOfAnyType() Dim myRefArg As Integer = 5 '排列Dim foo = Mock。Create(Of IFoo)() Mock.Arrange(Function() foo.Bar(Arg.AnyInt)).Returns(10) '作为整数= foo.Bar(myRefArg) '维护维护。AreEqual(10, actual)断言。AreEqual(5, myRefArg)结束Sub 注意,的使用价值字段在匹配器的末尾(
Arg.Ref (Arg.AnyInt)
value)是使用此特性所需要的。这里我们将使用
参数。裁判
Matcher,以匹配将被调用的ref参数为已知的函数类型和value interval。我们将使用Arg.Matches T < > ()
对于这个。[TestMethod] public void matchingrefparameterswith特化(){int myRefArg = 11;//排列变量foo = Mock.Create
();Mock.Arrange(() => foo。酒吧(ref Arg.Ref(参数。匹配 (x=> x > 10)).Value)).Returns(10); // Act int actual = foo.Bar(ref myRefArg); // Assert Assert.AreEqual(10, actual); Assert.AreEqual(11, myRefArg); } Public Sub matchingrefparameterswith特化()Dim myRefArg As Integer = 11 '排列Dim foo = Mock。Create(Of IFoo)() Mock.Arrange(Function() foo.Bar(Arg. bar)匹配(整数)(函数(x) x > 10)))。Returns(10) ' Act Dim actual As Integer = foo.Bar(myRefArg) ' Assert Assert.AreEqual(10, actual) Assert.AreEqual(11, myRefArg) End Sub 注意,的使用价值字段在匹配器的末尾(
Arg.Ref(参数。匹配
value)是使用此特性所需要的。(x => x > 10))