我的项目在规模和功能方面都在不断增长,所以我决定使用NUnit测试一些功能但是我面临的问题是大多数方法都是静态的,所以首先要发现的是创建公共方法我从Unit Test类调用它们但是那些公共方法开始很多,所以我想知道如果不是在主类中创建新的Public方法,我应该创建一个接口或者如果静态方法应该是Public并且是使用类中间实例化。
这是我的程序结构的一个例子,
namespace Mynamespace
{
public class Foo
{
InsertUser();
SortUser();
}
static void InsertUser()
{
}
static void SortUser()
{
}
//Here start the public methods to be called from the unit test class
public DoSort()
{
InsertUser();
SortUser();
}
}
将程序的主要逻辑和测试类分开的最佳方法是什么?
谢谢,
答案 0 :(得分:1)
不是保留静态方法和添加非静态方法,最好将所有方法从静态转换为实例方法,并提取Foo类客户端依赖的抽象:
public interface IFoo
{
void InsertUser();
void SortUser();
}
public class Foo : IFoo
{
void InsertUser() { ... }
void SortUser() { ... }
}
静态成员将耦合引入您的应用程序。模拟静态成员真的很头疼。您应该program to abstraction, instead of programing to implementation以使您的代码可以测试并loosely coupled。当您的代码依赖于接口而不是静态类时,您可以轻松地mock这种依赖:
Mock<IFoo> fooMock = new Mock<IFoo>();
fooMock.Setup(f => f.InsertUser()).Throws<InvalidOperationException>();
var sut = new ClassUnderTest(fooMock.Object);
fooMock.VerifyAll();
如果你真的需要在全局范围内访问这些方法(这不是一个好主意 - 它是一种程序化的编程风格),那么将你的类实现为Singleton:
public class Foo : IFoo
{
public static Foo Instance = new Foo(); // simple singleton implementation
private Foo() { }
void InsertUser() { ... }
void SortUser() { ... }
}
您可以在应用程序的任何位置获取类实例
IFoo foo = Foo.Instance;
foo.SortUser();
答案 1 :(得分:1)
在我看来,你应该让你的真正的类和你的单元类都实现一个通用的接口,如下所示:
interface IFoo
{
void InsertUser();
void SortUser();
}
对于您的实际实施,请使用:
public class RealFoo : IFoo
{
public void InsertUser()
{
throw new NotImplementedException();
}
public void SortUser()
{
throw new NotImplementedException();
}
}
对于您的测试类,请使用:
public class FakeFoo : IFoo
{
public void InsertUser()
{
throw new NotImplementedException();
}
public void SortUser()
{
throw new NotImplementedException();
}
}
注意:您的FakeFoo
类不需要与RealFoo
类位于同一位置,而是您的IFoo
接口定义应该被每个项目引用(一个用于实际实现,另一个用于测试项目。)
如果你的IFoo
界面变得太大(阅读:方法太多),那么你可以使用Repository Pattern
,它会将你的方法划分为更接近功能性的接口。