我目前正在我的mvc应用程序中测试控制器,我正在创建一个虚假的存储库进行测试。但是,我似乎在编写更多代码并花费更多时间来制作假货,而不是在实际存储库中。这是对的吗?
我的代码如下:
控制器
public partial class SomeController : Controller
{
IRepository repository;
public SomeController(IRepository rep)
{
repository = rep;
}
public virtaul ActionResult Index()
{
// Some logic
var model = repository.GetSomething();
return View(model);
}
}
IRepository
public interface IRepository
{
Something GetSomething();
}
假存储库
public class FakeRepository : IRepository
{
private List<Something> somethingList;
public FakeRepository(List<Something> somethings)
{
somthingList = somthings;
}
public Something GetSomething()
{
return somethingList;
}
}
虚假数据
class FakeSomethingData
{
public static List<Something> CreateSomethingData()
{
var somethings = new List<Something>();
for (int i = 0; i < 100; i++)
{
somethings.Add(new Something
{
value1 = String.Format("value{0}", i),
value2 = String.Format("value{0}", i),
value3 = String.Format("value{0}", i)
});
}
return somethings;
}
}
实际测试
[TestClass]
public class SomethingControllerTest
{
SomethingController CreateSomethingController()
{
var testData = FakeSomethingData.CreateSomethingData();
var repository = new FakeSomethingRepository(testData);
SomethingController controller = new SomethingController(repository);
return controller;
}
[TestMethod]
public void SomeTest()
{
// Arrange
var controller = CreateSomethingController();
// Act
// Some test here
// Arrange
}
}
所有这些似乎都是很多额外的代码,特别是因为我有多个存储库。有更有效的方法吗?也许使用嘲笑?
由于
答案 0 :(得分:2)
您可以模拟存储库。
答案 1 :(得分:1)
正如CD提议的那样,使用模拟框架。我也使用Moq,而对于Moq,您的测试代码可以重构为:
// Arrange
var repoMock = new Mock<IRepository>();
repoMock.Setup(r => r.GetSomething()).Returns(TestData.SomeThings);
var controller = new SomethingController(repoMock.Object);
// Act
controller.DoStuff();
// Assert
...
我通常发现将所有测试数据放在一个单独的TestData
类中,并且所有内容都具有静态属性是很方便的 - 这样我知道我在每个测试中使用相同的数据进行测试。这是您在TestData
中为此示例所需的内容:
public static List<Something> SomeThings
{
get
{
var somethings = new List<Something>();
for (int i = 0; i < 100; i++)
{
somethings.Add(new Something
{
value1 = String.Format("value{0}", i),
value2 = String.Format("value{0}", i),
value3 = String.Format("value{0}", i)
});
}
return somethings;
}
}
答案 2 :(得分:0)
更好的方法是使用Dev Magic Fake,这样你就可以模拟数据库并且也可以是永久性的,你也可以模拟UI
只需添加对DevMagicFake.dll的引用
您可以编写以下代码:
[HttpPost]
public ActionResult Create(VendorForm vendorForm)
{
var repoistory = new FakeRepository<VendorForm>();
repoistory.Save(vendorForm);
return View("Page", repoistory.GetAll());
}
这会将VendorForm永久保存在内存中,您可以随时检索它 您还可以为模型中的此对象或任何其他对象生成数据,有关Dev Magic Fake的更多信息,请参阅CodePlex上的以下链接:
http://devmagicfake.codeplex.com
由于
M.Radwan