0

我正在尝试做一些单元测试,我需要虚拟数据。其中一些数据我需要有特定的值,其他的只是随机的。

例如,我的服务层中有一个“CreateProduct”方法,我想知道在我的单元测试中使用这些方法而不是手工制作产品是否是个好主意。

从表面上看,这似乎是一个好主意,但我担心我可能需要嘲笑或其他东西才能成功通过这种方法。

CreateProduct 将尝试将产品保存到数据库中,但我已经有一个标志可以阻止保存发生(用于工作单元场景的回滚情况)。

我正在使用 EF 6-rc1 并使用 moq 模拟 DataContext 并且我将使用 AutoFixture 但它不适用于这个 secnario 并且我开始觉得我一次使用了太多新工具所以也许我现在应该手动完成。

4

2 回答 2

1

If you want to Unit Test something, you'll just want to test the unit. If you use a method in the servicelayer to generate some fake data, the unit test is not only testing the unit under test, but also the method in the service layer.

So the answer to your question: no, it is not a good idea to use the service layer to dummy data

于 2013-10-13T19:30:06.577 回答
1

It's hard to tell exactly what you are doing without a code example, but I sometimes use this implementation of an IDataSet that uses a List in memory. Typical usage would be something like:

using System.Data.Entity;
using System.Linq;
using Moq;
using NUnit.Framework;

namespace EFMock
{
    internal interface IDataContext
    {
        IDbSet<DataItem> DataItems { get; set; }
    }

    class DataContext : DbContext, IDataContext
    {
        public IDbSet<DataItem> DataItems{ get; set; }
    }

    class DataItem
    {
        public int SomeNumber { get; set; }
        public string SomeString { get; set; }
    }

    /* ----------- */

    class DataUsage
    {
        public int DoSomething(IDataContext dataContext)
        {
            return dataContext.DataItems.Sum(x => x.SomeNumber);
        }
    }

    /* ----------- */

    [TestFixture]
    class TestClass
    {
        [Test]
        public void SomeTest()
        {
            var fakeDataItems = new [] {
                new DataItem { SomeNumber = 1, SomeString = "One" },
                new DataItem { SomeNumber = 2, SomeString = "Two" }};

            var mockDataContext = new Mock<IDataContext>();
            mockDataContext.SetupGet(x => x.DataItems).Returns(new FakeDbSet<DataItem>(fakeDataItems));

            var dataUsage = new DataUsage();
            var result = dataUsage.DoSomething(mockDataContext.Object);

            Assert.AreEqual(2, result);
        }
    }
}

I also have a NuGet package named "FakeO" that you can use to create some fake objects, where some data is a specific value and some is random:

var fakeDataItems = FakeO.Create.Fake<DataItem>(10, // create an IEnumerable of 10 items
    x => x.SomeNumber = FakeO.Number.Next(),        // set to a random number
    x => x.SomeString = "Always This String");      // set to a specific string

One thing to keep in mind with this kind of testing is that using an IQueryable against a List will use Linq2Objects and not Linq2Entities, so results of some Linq queries will be different.

于 2013-10-13T20:33:03.930 回答