[英]How can I mock this static method
I have this code: 我有以下代码:
public static bool IsValidVoucher(string id)
{
//read tsv files
var temp1 = AppData.GetAppData("stringval");
// code that need to be tested
return true;
}
And I like to create unit test, but how can I mock AppData.GetAppData("stringval")
to whatever I want the value is, so I can test the rest of code. 而且我喜欢创建单元测试,但是如何将AppData.GetAppData("stringval")
模拟为我想要的值,因此可以测试其余代码。
The AppData class is: AppData类为:
public class AppData
{
public static object GetAppData(string name)
{
//...
}
}
Static methods cannot be mocked in an easy way . 静态方法不能简单地模拟。 You basically have two choices: 您基本上有两个选择:
If you own the AppData
class, change the implementation to implement an interface (eg IAppData
) and remove the static
modifier on the GetAppData
method so you can mock it. 如果您拥有AppData
类,请更改实现以实现接口(例如IAppData
),并删除GetAppData
方法上的static
修饰符,以便对其进行模拟。
public interface IAppData { object GetAppData(string id); } public class AppData : IAppData { public object GetAppData(string id) {} } public class Foo { private readonly IAppData _appData; public Foo(IAppData appData) { _appData = appData; } public bool IsValidVoucher(string id) { // Call through object instance instead for class reference var temp1 = _appData.GetAppData("stringval"); } }
If you do not own the AppData
class, use a wrapper class (eg AppDataWrapper
) that implements an interface and call that method from IsValidVoucher
instead: 如果您不拥有AppData
类,请使用实现接口的包装器类(例如AppDataWrapper
),然后从IsValidVoucher
调用该方法:
public interface IAppData { object GetAppData(string id); } public class AppDataWrapper : IAppData { public object GetAppData(string id) { return AppData.GetAppData(id); } } public class Foo { private readonly IAppData _appData; public Foo(IAppData appData) { _appData = appData; } public bool IsValidVoucher(string id) { var temp1 = _appData.GetAppData("stringval"); } }
You can then unit test Foo
using Moq (using xunit as an example here): 然后,您可以使用Moq对Foo
进行单元测试(此处以xunit为例):
public class FooTests
{
private readonly IAppData _mockAppData;
public FooTests()
{
var mockAppData = new Mock<IAppData>();
mockAppData.Setup(m => m.GetAppData(It.IsAny<string>)).Returns("my test value");
_mockAppData = mockAppData.Object;
}
[Fact]
public void IsValidVoucher_ValidAppData_Returns()
{
var foo = new Foo(_mockAppData);
// Unit test foo.IsValidVoucher
}
}
Well, I think everyone's comments so far is technically correct - using something like RhinoMocks
or Moq
, you really can't mock static methods in a facile, straightforward manner. 好吧,我认为到目前为止,每个人的评论在技术上都是正确的-使用RhinoMocks
或Moq
类的东西,您真的无法以便捷,直接的方式模拟静态方法。
But using Moles
, you definitely can. 但是使用Moles
,您肯定可以。 So if you have significant (currently) untestable code that reside within static methods, I think you should be looking into Moles. 因此,如果您有大量(当前)不可测试的代码驻留在静态方法中,那么我认为您应该研究Moles。
(This link is a bit dated but I still find it helpful) http://research.microsoft.com/en-us/projects/pex/molesmanual.pdf (此链接有些过时,但我仍然觉得有帮助) http://research.microsoft.com/zh-cn/projects/pex/molesmanual.pdf
(Key text) (关键文字)
Moles can be used to detour any .NET method, including non-virtual and static methods in sealed types. Moles可用于绕开任何.NET方法,包括密封类型的非虚拟方法和静态方法。
How it works: Suppose you have a typical situation like this: 工作原理:假设您遇到的典型情况如下:
public static class SomeStaticClass
{
public static int SomeStaticMethod(string s)
{
return "Static method called: " + s;
}
}
public class SomeInstanceClass
{
public string SomeInstanceMethod(string s)
{
return SomeStaticClass.SomeStaticMethod(s);
}
}
Using Moles, your test code would look like this: 使用Moles,您的测试代码如下所示:
[TestMethod()]
[HostType("Moles")]
public void ShouldBeAbleToTestStaticMethod()
{
var instance = new SomeInstanceClass();
var testValue = instance.SomeInstanceMethod("Some test string");
SomeStaticClass.SomeStaticMethod = (s) => "Moled you! " + s;
Assert.That(testValue, Is.EqualTo("Moled you! Some test string"); // sorry, this has code smell, lol
}
Of course you need to set up Moles into your test project, so be sure to look it up - lots of web resources to help you on your way. 当然,您需要在测试项目中设置Moles,因此一定要查找它-大量的网络资源可以帮助您。
Some helpful posts: 一些有用的帖子:
https://msdn.microsoft.com/en-us/library/ff798308.aspx https://msdn.microsoft.com/zh-CN/library/ff798308.aspx
http://adventuresdotnet.blogspot.com/2011/03/mocking-static-methods-for-unit-testing.html http://adventuresdotnet.blogspot.com/2011/03/mocking-static-methods-for-unit-testing.html
https://wannabeegeek.wordpress.com/2013/03/13/unit-testing-made-easy-with-moles-part-i/ https://wannabeegeek.wordpress.com/2013/03/13/unit-testing-made-easy-with-moles-part-i/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.