Модульное тестирование в C # с использованием поддельного контекста базы данных с использованием HashSet (множественный код) (New Q) - PullRequest
13 голосов
/ 14 мая 2011

Короткая версия:

В этом видео мистер Скотт Аллен объясняет, как проверить контроллер .Но он не показывает полный код класса: FakeDbContext.Есть кто-то, кто может помочь мне закончить это?Он показывает класс в 06:15 в видео для «тестирования контроллеров».

Длинная версия

В школе у ​​меня есть факультатив, где мы изучаем C #,Мой экзаменационный проект - это сайт ASP, использующий MVC3.Чтобы научиться этому быстро, я видел видео с PluralSight.Мой вопрос о каком-то коде, который есть в этом видео Он объясняет, как тестировать контроллеры.Итак, я попытался: я сделал контроллер, который имеет простой метод индекса:

public class Round1Controller : Controller
{
    IDbContext _db;

    public Round1Controller()
    {
        _db = new Entities();
    }

    public Round1Controller(IDbContext db)
    {
        _db = db;
    }

    public ActionResult Index()
    {
        var model = _db.ELECTIVES.ToList();

        return View(model);
    }

Как вы можете видеть, я уже пытался создать контекст.Метод индекса - это тот, который я хочу протестировать.Следующее, что он делает, это делает класс под названием FakeDbContext в тестовом проекте.

Но, к сожалению, он показывает только часть кода, и я потратил много часов, пытаясь выяснить,как он создает get метод для HashSet.

Вот код, который вы можете увидеть из видео:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EESS.Models;

namespace EESS.Tests
{
class FakeDbContext : IDbContext
{
    public IQueryable<Restaurant> Restaurants
    {
        get { return _map.Get<Restaurant>().asQueryable(); }
        set { _map.Use<Restaurant>(value); }
    }
    public IQueryable<Review> Reviews
    {
        get { return _map.Get<Review>().asQueryable(); }
        set { _map.Use<Review>(value); }
    }

    public int SaveChanges()
    {
        ChangesSaved = true;
        return 0;
    }

    public bool ChangesSaved { get; set; }

    public T Attach<T>(T entity) where T : class
    {
        _map.Get<T>().Add(entity);
        return entity;
    }
    public T Add<T>(T entity) where T : class
    {
        _map.Get<T>().Add(entity);
        return entity;
    }

    public T Delete<T>(T entity) where T : class
    {
        _map.Get<T>().Remove(entity);
        return entity;
    }

    SetMap _map = new SetMap();

    class SetMap : KeyedCollection<Type, object>
    {
        public HashSet<T> Use<T>(IEnumerable<T> sourceData)
        {
            var set = new HashSet<T>(sourceData);
            if (Contains(typeof(T)))
            {
                Remove(typeof(T));
            }
            Add(set);
            return set;
        }
    }
}
}

Чтобы закончить длинную версию, моя проблема в том,я получаю ошибку на _Map.Get.Does not contain a definition or extension method.

РЕДАКТИРОВАТЬ!ЧАСТЬ 2:

После ответа @xelibrion он наконец заработал.

Но потом возникла другая проблема.

Класс IDbContext выглядит следующим образом:

public interface IDbContext
    {
        IQueryable<ELECTIVES> ELECTIVES { get; }
        int SaveChanges();
        T Attach<T>(T entity) where T : class;
        T Add<T>(T entity) where T : class;
        T Delete<T>(T entity) where T : class;
    }

Когда я добавляю этот интерфейс в мой класс сущностей, он ожидает, что я реализую методы.PluralSight реализует их так:

public DbSet<ELECTIVES> electives { get; set; }

    IQueryable<ELECTIVES> IDbContext.ELECTIVES
    {
        get { return electives; }
    }

    int IDbContext.SaveChanges()
    {
        return SaveChanges();
    }

    T IDbContext.Add<T>(T entity)
    {
        return Set<T>().Add(entity);
    }

    T IDbContext.Delete<T>(T entity)
    {
        return Set<T>().Remove(entity);
    }

    T IDbContext.Attach<T>(T entity)
    {

        var entry = Entry(entity);
        entry.State = System.Data.EntityState.Modified;
        return entity;
        return Set<T>().Add(entity);
    }

Но мой класс "_dbModel.Designer.cs" из моей модели сущностей не знает, что такое Set и Entry, и предлагает только сделать заглушку метода.В этом классе гораздо больше кода, поэтому, если нужно, просто спросите об остальном :) Я изменил Restaurants на Electives, так как это имя таблицы в моей БД.

Это «использование», которое у меня есть?забыли?Я снова видел видео, и у него нет класса-заглушки в своем классе БД.

1 Ответ

11 голосов
/ 14 мая 2011

Полагаю, полная версия класса SetMap должна выглядеть следующим образом

class SetMap : KeyedCollection<Type, object>
{
    public HashSet<T> Use<T>(IEnumerable<T> sourceData)
    {
        var set = new HashSet<T>(sourceData);
        if (Contains(typeof(T)))
        {
            Remove(typeof(T));
        }
        Add(set);
        return set;
    }

    public HashSet<T> Get <T>()
    {
        return (HashSet<T>) this[typeof(T)];
    }

    protected override Type GetKeyForItem(object item)
    {
        return item.GetType().GetGenericArguments().Single();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...