asp.net mvc - 如何快速有效地创建假测试对象

时间:2010-06-18 08:54:29

标签: asp.net-mvc model-view-controller unit-testing

我目前正在我的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
    }
}

所有这些似乎都是很多额外的代码,特别是因为我有多个存储库。有更有效的方法吗?也许使用嘲笑?

由于

3 个答案:

答案 0 :(得分:2)

您可以模拟存储库。

(我使用MoqMock a database repository using Moq

答案 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