0

我正在尝试将测试层带入我的项目,但我没有到达那里:(希望有人可以帮助我。

控制器(基于 Automapper 映射和依赖注入容器):

    public virtual ActionResult SearchCategories(string keywords)
    {
        var result = _categoryService.SearchCategories(keywords);

        var resultViewModel = Mapper.
            Map<IList<SearchCategoriesDto>, 
                IList<SearchCategoriesViewModel>>(result);

        return View(resultViewModel);
    }    

服务层:

   public IList<SearchCategoriesDto> SearchCategories(String keywords)
    {
        // Find the keywords in the Keywords table
        var keywordQuery = _keywordRepository.Query;

        foreach (string keyword in splitKeywords)
        {
            keywordQuery = keywordQuery.Where(p => p.Name == keyword);
        }

        // Get the Categories from the Search
        var keywordAdCategoryQuery = _keywordAdCategoryRepository.Query;
        var categoryQuery = _categoryRepository.Query;

        var query = from k in keywordQuery
                    join kac in keywordAdCategoryQuery on k.Id equals kac.Keyword_Id
                    join c in categoryQuery on kac.Category_Id equals c.Id
                    select new SearchCategoriesDto
                    {
                        Id = c.Id,
                        Name = c.Name,
                        SearchCount = keywordAdCategoryQuery
                             .Where(s => s.Category_Id == c.Id)
                             .GroupBy(p => p.Ad_Id).Count(),
                        ListController = c.ListController,
                        ListAction = c.ListAction
                    };

        var searchResults = query.Distinct().ToList();

        return searchResults;
    }

测试完成但不工作:

    [TestMethod]
    public void Home_SearchCategories_Test()
    {
        // Setup
        var catetoryService = new CategoryService(
                                   _categoryRepository, 
                                   _keywordRepository, 
                                   _keywordAdCategoryRepository);

        // Act
        var result = catetoryService.SearchCategories("audi");

        // Add verifications here
        Assert.IsTrue(result.Count > 0);
    }

谢谢。

4

2 回答 2

1

我假设您想使用真实的存储库和数据库为您的类别服务创建一个集成测试。(与单元测试相反,您将在这些存储库中使用 stub\mocks 并单独测试服务类)

因此,您将拥有一个分离的测试程序集,您将在其中添加集成测试,例如在服务级别为集成测试提供一个类。然后,在该类上,您将在运行每个测试之前创建所有存储库和 CategoryService 的实例,在具有属性 [TestInitialize] 的方法上。(具有此属性的方法将在每次测试之前由 msTest 运行)

由于您还真正地使用数据库,因此您希望确保已使用的所有资源都已处理完毕。例如,处理实体框架上下文。在这种情况下,您将添加一个具有 [TestCleanup] 属性的方法,您将在其中执行所需的任何清理逻辑。(具有此属性的方法将在每次测试后由 msTest 运行)

使用这些方法,您将确保每次测试都有一个新的服务和存储库实例。然后,您将按照 AAA 模式(安排、行动、断言)实施每个单独的集成测试

因此,带有单个测试的集成测试类的示例可能如下所示:

public class CategoryServiceIntegrationTest
{
    //dependencies of your class under test
    private ICategoryRepository _categoryRepository; 
    private IKeywordRepository _keywordRepository;
    private IKeywordAdCategoryRepository _keywordAdCategoryRepository;

    //your class under test
    private CategoryService _categoryService;

    [TestInitialize]
    public void InitializeBeforeRunningATest()
    {
        //manually create instances of the classes implementing the repositories
        //I don´t know about how they are implemented but I guess
        //you would need to provide the name of a connection string in the config file (in that case this should be in a config file of the test project)
        //,the connection string itself
        //or maybe you need to initialize an entity framework context
        _categoryRepository = new CategoryRepository( /*whatever you need to provide*/);
        _keywordRepository = new KeywordRepository( /*whatever you need to provide*/);
        _keywordAdCategoryRepository = new KeywordAdCategoryRepository( /*whatever you need to provide*/);

        //Create the class under test with all repositories dependencies          
        //as it is an integration test, they are your real objects and not mocks\stubs
        _categoryService = new CategoryService(_categoryRepository, 
                                               _keywordRepository,
                                               _keywordAdCategoryRepository);
    }

    [TestCleanup]
    public void CleanDatabaseResources()
    {
        //just in case you need to do something like disposing an EF context object          
    }

    [TestMethod]
    public void Home_SearchCategories_Test()
    {
        // Arrange
        var keywords = "audi";

        // Act (the _categoryService instance was created in the initialize method)
        var result = _categoryService.SearchCategories(keywords);

        // Assert
        Assert.IsTrue(result.Count > 0);
    }
}
于 2012-11-23T19:38:59.620 回答
0

使用 Autofac、Automapper 为服务(在本例中为类别服务)构建集成测试的解决方案(在此服务中不是必需的,但如果有必要,您需要放入 TestInitialize 方法,如您在以下解决方案中的注释行)和 Daniel JG 帮助下的实体框架(感谢 Daniel):

首先,我使用 MSTest 创建了一个单独的测试项目(只是因为有很多关于它的文档)。

其次,您需要将实体框架的连接字符串放在测试数据所在的位置:

<connectionStrings>
    <add name="DB" connectionString="Data Source=.\sqlexpress;Database=DBNAME;UID=DBUSER;pwd=DBPASSWORD;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
</connectionStrings>

在<configSections>之后的<configSections>部分

第三,您为测试创建类:

namespace Heelp.Tests
{
    [TestClass]
    public class CategoryServiceIntegrationTest
    {
        // Respositories dependencies
        private IRepository<Category> _categoryRepository;
        private IRepository<Keyword> _keywordRepository;
        private IRepository<KeywordAdCategory> _keywordAdCategoryRepository;

        // Service under test: Category Service
        private CategoryService _categoryService;

        // Context under test: HeelpDB Connection String in app.config
        private HeelpDbContext db;

        [TestInitialize]
        public void InitializeBeforeRunningATest()
        {
            // IoC dependencies registrations
            AutofacConfig.RegisterDependencies();

            // HERE YOU CAN CALL THE AUTOMAPPER CONFIGURE METHOD
            // IN MY PROJECT I USE AutoMapperConfiguration.Configure();  
            // IT'S LOCATED IN THE App_Start FOLDER IN THE AutoMapperConfig.cs CLASS
            // CALLED FROM GLOBAL.ASAX Application_Start() METHOD

            // Database context initialization
            db = new HeelpDbContext();

            // Repositories initialization
            _categoryRepository = new Repository<Category>(db);
            _keywordRepository = new Repository<Keyword>(db);
            _keywordAdCategoryRepository = new Repository<KeywordAdCategory>(db); 

            // Service initialization
            _categoryService = new CategoryService(_categoryRepository,
                                                   _keywordRepository,
                                                   _keywordAdCategoryRepository);
        }

        [TestCleanup]
        public void CleanDatabaseResources()
        {
            // Release the Entity Framework Context for other tests that will create a fresh new context.
            // With this method, we will make sure that we have a fresh service and repositories instances on each test. 
            db.Dispose();
        }

        [TestMethod]
        public void Home_SearchCategories_Test()
        {
            // Arrange
            var keywords = "audi";

            // Act (the _categoryService instance was created in the initialize method)
            var result = _categoryService.SearchCategories(keywords);

            // Assert
            Assert.IsTrue(result.Count > 0);
        }
    }

}

现在你只需要运行测试看看它是否通过了。

为了保证集成测试,我会推荐与原始/生产数据库在表格方面相同的第二个数据库,但只有您的测试数据。

这将确保测试结果根据您的测试数据保持不变。

唯一的缺点是您需要对表进行sincronized,但您可以使用Simego 的SQL Admin Studio Freeware Tool 来实现这一点。

问候。

于 2012-11-24T17:35:38.580 回答