0

Projectエンティティのセットを含むWordエンティティがあります。私は実体WordsRepositoryに依存します。Projectプロジェクトに含まれる一連の単語に対して機能する必要があります。

public interface IWordsRepository
{
    List<Word> FetchAll();
}
public class WordsRepository : IWordsRepository
{
    private readonly Project _project;

    public WordsRepository(Project project)
    {
        if (project == null)
            throw new ArgumentNullException("project");
        this._project = project;
    }
    public List<Word> FetchAll()
    {
        // code for retrieveing words for the project from the database
    }        
}

それでは、もう少し深く掘り下げましょう。これが私のProjectsModelです。

public class ProjectsModel
{
    private readonly IProjectsRepository _rep;
    private IWordsRepository _wordsRep;
    private IProjectsModelObserver _presenter;

    // Regular contructor for usual purpose
    public ProjectsModel()
    {            
        this._rep = new ProjectsRepository(Program.context);
    }

    public ProjectsModel(IProjectsRepository repository)
    {
        this._rep = repository;
    }

    public virtual void AttachPresenter(IProjectsModelObserver observer)
    {
        this._presenter = observer;
    }

    public List<Project> projects
    {
        get
        {
            List<Project> tmpList = _rep.FetchAll();
            return (tmpList != null) ? tmpList : new List<Project>();
        }
    }

    private Project _selectedProject;
    public Project selectedProject
    {
        get
        {
            if (_selectedProject == null)
                _selectedProject = projects.FirstOrDefault();
            return _selectedProject;
        }
        set
        {
            if (!projects.Contains(value))
                throw new InvalidOperationException("Project not in the Projects list");

            _selectedProject = projects[projects.IndexOf(value)];
            // Recreating Words repository depending on project
            // Here is my issue:
            // As I should recreate the Words repository here, passing a new selected project 
            // how can I mock it and make this class testable?
            this._wordsRep = new WordsRepository(this._selectedProject);

            if (this._presenter != null)
                this._presenter.SelectedProjectChanged(_selectedProject);
        }
    }

    private List<Word> _words;
    public List<Word> Words
    {
        get
        {
          // Fetching set of words in Project. Just invoking a words repository
        }
    }
}

モデルの選択したプロジェクトが変更されると、を再作成する必要WordsRepositoryがありますが、この方法ではテストできません。

どうすればそれをモックできますか?

4

3 に答える 3

2

新しい を作成するには、ファクトリを使用する必要がありますWordsRepository。おそらくご存じのとおり、newコード内にこの単語が表示される場合は、要求されているインスタンスを提供する Factory クラスを作成することをお勧めします。これにより、ファクトリをモックして、テスト時に必要なインスタンスを返すことができるからです。

したがって、次のように変更します。

  _WordsRep = WordsRepositoryFactory.CreateNewRepository(_selectedProject);
于 2012-05-10T14:50:59.567 に答える
1

Managed Extensibility Framework を調べてください。基本的に、そのインターフェイスに複数の実装を持つ単一のインターフェイスがあります。ただし、実行時にこれらの実装を相互に切り替えられるようにする必要があります。そのためには、どちらの実装に対しても静的にリンクすることはできず、フレームワークがどちらを使用するかを決定できるようにする必要があります。

MEF では [Import(typeof(IWordsRepository))] が可能です。これにより、別の実装を展開アイテムとしてドロップできます。コードは次のようになります。

[Export(typeof(IWordsRepository))]
public class WordsRepository : IWordsRepository
{
   public List<Word> FetchAll()
   {
       //this class will hit the database
   }
}



[Export(typeof(IWordsRepository))]
public class WordsRepositoryTest : IWordsRepository
{
   public List<Word> FetchAll()
   {
        //this class will not go to the database, maybe an xml file or something.    
   } 
}

次に、ProjectsModel は以下を使用します。

[Import(typeof(IWordsRepository))]
IWordsRepository _repo;

これら 2 つのタイプを 2 つの異なる dll に格納し、テスト タイプを単体テストの展開項目としてドロップします。ドロップインした実装が使用されます。

MEF の詳細: http://msdn.microsoft.com/en-us/library/dd460648.aspx

展開項目の詳細: http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.deploymentitemattribute(v=vs.80).aspx

于 2012-05-10T14:52:18.743 に答える
0

私はあなたのコードを理解するのが難しいと思っていますが、Tejsが言及しているように、ファクトリはオプションです。別の可能性は、セッターではなく、SetSelectedProject(IWordsRepository)メソッドを使用することです。これは、特定のプロジェクトで可能である場合とそうでない場合があります。

于 2012-05-10T14:55:35.213 に答える