Telerik JustMock?下载30天免费试用

静态模拟

中支持的高级特性之一是静态模拟Telerik®JustMock.它允许你伪造静态构造函数,方法和属性调用,设置期望和验证结果使用AAA原则。

我们可以将静态模拟分为以下几个主要部分:

  • 静态构造函数模拟
  • 静态方法模拟
  • 扩展方法模拟

这是一个高架特征。指主题,以了解更多关于Telerik JustMock的商业版本和免费版本之间的差异。

在本主题中,我们将使用以下示例代码来演示如何模拟静态构造函数、方法和属性。

公共类Foo{静态Foo(){抛出新的NotImplementedException();} public static void Submit() {} public static int Execute(int arg) {throw new NotImplementedException();} public static int FooProp {get{抛出新的NotImplementedException();} set{抛出新的NotImplementedException();}}}内部类FooInternal{内部静态void DoIt(){抛出新的NotImplementedException();}}公共静态类FooStatic{公共静态void Do(){抛出新的NotImplementedException();}}
公共类Foo共享子新()抛出新NotImplementedException()结束子公共共享子提交()抛出新的NotImplementedException()子公共共享函数执行结束(arg整数)整数把新NotImplementedException()结束函数公共共享属性为必选的整数买把新NotImplementedException()结束获得组(值为整数)把新NotImplementedException()端设置结束属性端类朋友类FooInternal朋友共享子DoIt()抛出新的NotImplementedException()结束子结束类Public非继承类FooStatic Private Sub New()结束子Public共享子抛出新的NotImplementedException()结束子结束类

重要的

要使用静态模拟,首先需要从菜单中启用JustMock,从而进入提升模式。如何启用/禁用

静态构造函数模拟

在下面的示例中,您将看到如何在模拟目标类型时指定静态构造函数的行为。您需要做的第一件事是为模拟所有静态调用设置目标类型。对象的下列调用之一可以完成此操作模拟。SetupStatic方法。

无效的模拟。SetupStatic(类型staticType);无效的模拟。SetupStatic(类型targetType,行为行为);无效的模拟。SetupStatic(类型staticType, StaticConstructor);无效的模拟。SetupStatic(类型targetType,行为行为,静态构造函数);

正如你所看到的,你有很多选择。您总是必须提供您想要为模拟设置的目标类的类型。您还可以指定模拟的行为。默认行为为的行为。宽松的

StaticConstructor参数定义静态构造函数的默认行为。可以从以下值中选择:

  • NonMocked
  • 嘲笑

此属性的默认值为NonMocked

让我们来看一个使用该类的完整示例喷火从示例代码开始。

[TestMethod] public void ShouldArrangeStaticFunction(){//安排Mock.SetupStatic(typeof(Foo), staticconstructor . mock);Int期望= 0;Mock.Arrange(() => Foo.FooProp).Returns(0);// Assert。AreEqual(预期,Foo.FooProp);}
公共子ShouldArrangeStaticFunction() '排列Mock.SetupStatic(GetType(Foo), staticconstructor . mock) Dim expected As Integer = 0 Mock.Arrange(Function() Foo. fooprop).Returns(0) '维护维护。AreEqual(expected, Foo.FooProp)结束Sub

这里我们已经设置了目标类型的静态构造函数mock喷火.使用StaticConstructor的调用中的参数SetupStatic方法的调用,因此要模拟对静态构造函数的调用Foo。喷火Prop不会扔NotImplementedException

通用静态方法模拟

让我们从最简单的示例开始,即如何模拟静态提交方法。首先,我们需要调用以下函数:

Mock.SetupStatic (typeof (Foo), StaticConstructor.Mocked);
Mock.SetupStatic(方法(Foo), StaticConstructor.Mocked)

这个调用设置喷火类型为静态模拟,并将所有静态方法准备为可mock。

这实际上是静态模拟和实例模拟之间的唯一区别。从现在开始,您可以继续模拟实例方法。

Foo.Submit ();
Foo.Submit ()

提交方法实现时抛出异常,但由于我们模拟了喷火不应抛出异常的类。最后,我们可以断言该方法实际上被调用了。

Mock.Assert(() => Foo.Submit());
Foo.Submit Mock.Assert(子()())

Mock.SetupStatic (typeof (Foo), StaticConstructor.Mocked);我们设置好了所有来自这个类的静态方法将被嘲笑。在某些情况下,您只需要模拟设置时使用的方法模拟。安排.要实现这一点,您需要设置M:Telerik.JustMock。行为严格的模拟。SetupStatic调用。

[TestMethod] [ExpectedException(typeof(StrictMockException))]公共无效shouldthrowwhen公证书(){//安排Mock.SetupStatic(typeof(Foo),行为。严格,StaticConstructor.Mocked);Mock.Arrange(() => Foo.Execute(10)).Returns(10);/ /维护维护。Foo.Execute AreEqual(10日(10));// Act //抛出MockException,因为没有与提交方法Foo.Submit()相关的安排;}
  Public Sub shouldthrowwhen公证书()'排列Mock.SetupStatic(GetType(Foo),行为。严格的, StaticConstructor.Mocked) Mock.Arrange(Function() Foo.Execute(10)).Returns(10) ' Assert Assert.AreEqual(10, Foo.Execute(10)) ' Act ' Throws MockException as there is no arrange associated with the Submit method. Foo.Submit() End Sub

一旦我们设置M:Telerik.JustMock。行为严格的,只有调用通过安排设置被模拟。其他调用将抛出MockException

下面是一个在f#中模拟静态方法的例子:

[] member this.ShouldMockStaticCall() = Mock. setupstatic () Mock。排列(fun ignore -> Foo.EchoStatic()).Returns(1);断言。AreEqual (Foo.EchoStatic ())
静态EchoStatic方法设置为返回1

模拟静态属性获取

你也可以设置一个静态属性get:

[TestMethod] public void ShouldFakeStaticPropertyGet(){//安排Mock.SetupStatic(typeof(Foo),行为。严格,StaticConstructor.Mocked);Bool called = false;Mock.Arrange(() => Foo.FooProp).DoInstead(() => {called = true;}) .Returns (1);// Assert. areequal必选1);Assert.IsTrue(称为);}
 Public Sub ShouldFakeStaticPropertyGet() '排列Mock.SetupStatic(GetType(Foo),行为。严格的, StaticConstructor.Mocked) Dim called As Boolean = False Mock.Arrange(Function() Foo.FooProp).DoInstead(Sub() called = True).Returns(1) ' Act Assert.AreEqual(Foo.FooProp, 1) Assert.IsTrue(called) End Sub

我们替换了的实际实现Foo。喷火PropCalled = true;并返回1.在执行操作之后,我们验证该方法是否实际被调用并返回值1

模拟静态属性集

现在,让我们模拟一个静态属性集。在下面的例子中,我们排列Foo。喷火Prop财产。我们使用DoInstead将局部布尔变量设置为真正的一旦它被分配10.在此之后,我们验证我们所期望的在我们的测试中确实发生了。

[TestMethod] public void ShouldFakeStaticPropertySet(){//安排Mock.SetupStatic(typeof(Foo),行为。严格,StaticConstructor.Mocked);Bool called = false;Mock.ArrangeSet(() => {Foo。FooProp = 10;}).DoInstead(() => {called = true;});// Act -这一行不应该抛出任何mockexception。Foo。喷火Prop = 10; // Assert Assert.IsTrue(called); }
 Public Sub ShouldFakeStaticPropertySet() '排列Mock.SetupStatic(GetType(Foo),行为。严格的, StaticConstructor.Mocked) Dim called As Boolean = False Mock.ArrangeSet(Sub() Foo.FooProp = 10).DoInstead(Sub() called = True) ' Act - this line should not throw any mockexception. Foo.FooProp = 10 ' Assert Assert.IsTrue(called) End Sub

模拟属性主题以了解有关模拟属性的更多信息。

模拟内部静态调用

更进一步,您可以模拟内部方法,如下面的示例所示。

[TestMethod] public void ShouldFakeInternalStaticCall() {// Arrange Mock.SetupStatic();// Act FooInternal.DoIt();}
公共子ShouldFakeInternalStaticCall() '安排模拟。SetupStatic(Of FooInternal)() ' Act FooInternal.DoIt() End Sub

在这里,叫FooInternal。DoIt不应抛出异常,因为允许设置静态内部方法。

模拟静态类

在演示的示例中,我们模拟的类本身是非静态类——只有方法是静态的。类的非泛型版本来模拟静态类模拟。SetupStatic方法,即。

[TestMethod] public void ShouldMockStaticClass() {// Arrange Mock.SetupStatic(typeof(FooStatic));//不抛出MockException FooStatic.Do();}
公共子ShouldMockStaticClass() '排列Mock.SetupStatic(GetType(FooStatic)) 'Act -不抛出MockException FooStatic。终止子

跨线程模拟静态成员

跨所有线程模拟静态成员是一种不安全的操作,可能会损害测试框架的稳定性。默认情况下,静态成员上的排列仅对当前线程有效。要使一个静态成员的排列在所有线程上都有效,在该排列中添加.OnAllThreads()子句:

Mock.Arrange(() => DateTime.Now)。返回(新DateTime ()) .OnAllThreads ();

模拟当前HttpContext

下面是一个如何模拟的例子当前HTTP上下文

我们安排了一个电话HttpContext。当前的设置局部变量为真正的.注意,原来的实现HttpContext。当前的不会被执行。

[TestMethod] public void ShouldAssertMockingHttpContext(){//排列bool called = false;Mock.Arrange(() => HttpContext.Current).DoInstead(() => called = true);// Act var ret = HttpContext.Current;// Assert. istrue(被调用);}
_ Public Sub ShouldAssertMockingHttpContext() '将Dim调用为Boolean = False Mock.Arrange(Function() HttpContext.Current).DoInstead(Sub() called = True) 'Act Dim ret = HttpContext。当前的' Assert Assert.IsTrue(called) End Sub

行动之后,我们验证我们的期望。

模拟扩展方法

扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊的静态方法,但是调用它们时就像调用扩展类型的实例方法一样。

模拟扩展方法类似于模拟任何实例方法。唯一的区别是我们不需要Mock.Create T < > ()默认情况下,将类初始化为扩展模拟的调用是局部的。

让我们看一个如何模拟扩展方法的示例。考虑下面的类:

公共类Bar{公共无效Execute(){抛出新的NotImplementedException();}}
公共类Bar公共子Execute()抛出新的NotImplementedException()结束子结束类

类的扩展方法喷火类:

public static class BarExtensions {public static int Echo(this Bar foo, int arg){返回默认值(int);}}
Public Module BarExtensions  Public Function Echo(foo As Bar, arg As Integer) As Integer Return 0 End Function结束模块

让我们来模拟一下回声扩展方法。

[TestMethod] public void ShouldFakeExtensionMethod(){//排列var foo = new Bar();Mock.Arrange(() => foo.Echo(10)).Returns(11);// Act var actual = foo.Echo(10);// Assert。实际AreEqual(11日);}
公共子ShouldFakeExtensionMethod() '排列Dim foo = New Bar() Mock.Arrange(Function() foo. echo (10)).Returns(11) 'Act Dim实际= foo.Echo(10) '维护维护。AreEqual(11, actual)结束

类的实例喷火类。注意,我们创建的是类的标准实例,而不是模拟实例。然后设置对的调用回声通过安排对于非静态方法,我们也是这样做的。最后,我们像往常一样断言返回值。

另请参阅

在本文中
Baidu
map