1

我的应用程序中有一个相当基本的 HomeController,我为它编写了一个测试类。在我的测试类上运行代码覆盖率分析后,我意识到我没有对默认构造函数进行任何测试。

这是我的家庭控制器

public class HomeController : BaseController
{
    private INewsRepository _newsRepository;
    private INewsletterRepository _newsletterRepository;
    private string _currentLanguage;

    public HomeController()
    {
        _newsRepository = NewsRepository.Current;
        _newsletterRepository = NewsletterRepository.Current;
        _currentLanguage = ApplicationConfig.Current.CurrentLanguage;
    }

    public HomeController(INewsRepository newsRepository, INewsletterRepository newsletterRepository, string currentLanguage)
    {
        _newsRepository = newsRepository;
        _newsletterRepository = newsletterRepository;
        _currentLanguage = currentLanguage;
    }

    public ActionResult Index()
    {
        return View();
    }

    public ActionResult LatestNews()
    {
        return View(_newsRepository.ListAll().Where(n => n.LanguageKey.ToLower() == _currentLanguage.ToLower()).OrderByDescending(n => n.Date).Take(10));
    }

    public ActionResult LatestNewsletters()
    {
        return View(_newsletterRepository.ListAll().Where(n => n.LanguageKey.ToLower() == _currentLanguage.ToLower()).OrderByDescending(n => n.Date).Take(10));
    }
}

这是我的测试课:

[TestClass]
public class HomeControllerTest
{
    private INewsletterRepository _mockNewsletterRepostiory = null;
    private INewsRepository _mockNewsRepostiory = null;
    private List<News> _fakeNewsList = new List<News> { 
            new News{Id = 0, Title = "some title", Date = new DateTime(1989, 2, 19), LanguageKey = "fa", Description = "some description"}, 
            new News{Id = 1, Title = "some title", Date = new DateTime(1989, 2, 20), LanguageKey = "fa", Description = "some description"}, 
            new News{Id = 2, Title = "some title", Date = new DateTime(1989, 2, 21), LanguageKey = "fa", Description = "some description"}, 
            new News{Id = 3, Title = "some title", Date = new DateTime(1989, 2, 22), LanguageKey = "fa", Description = "some description"}
        };
    private List<Newsletter> _fakeNewsletterList = new List<Newsletter>
        {
            new Newsletter{ Id = 0, Description = "some description", UrlKey = "first-newsletter", Title = "some title", SendDate = null, NewsletterContents = null, LanguageKey = "fa", Date = new DateTime(1989, 2, 19) },
            new Newsletter{ Id = 1, Description = "some description", UrlKey = "first-newsletter", Title = "some title", SendDate = null, NewsletterContents = null, LanguageKey = "fa", Date = new DateTime(1989, 2, 20) },
            new Newsletter{ Id = 2, Description = "some description", UrlKey = "first-newsletter", Title = "some title", SendDate = null, NewsletterContents = null, LanguageKey = "fa", Date = new DateTime(1989, 2, 21) },
            new Newsletter{ Id = 3, Description = "some description", UrlKey = "first-newsletter", Title = "some title", SendDate = null, NewsletterContents = null, LanguageKey = "fa", Date = new DateTime(1989, 2, 22) }
        };

    [TestInitialize]
    public void Setup()
    {
        // Mock News Repository            
        var mockNewsRepository = MockRepository.GenerateStub<INewsRepository>();
        mockNewsRepository.Stub(m => m.ListAll()).Return(_fakeNewsList.AsQueryable());

        // Mock Newsletter Repository
        var mockNewsletterRopository = MockRepository.GenerateStub<INewsletterRepository>();
        mockNewsletterRopository.Stub(m => m.ListAll()).Return(_fakeNewsletterList.AsQueryable());

        _mockNewsletterRepostiory = mockNewsletterRopository;
        _mockNewsRepostiory = mockNewsRepository;
    }

    [TestMethod]
    public void IndexReturnsView()
    {
        // Arrange
        HomeController homeController = new HomeController(_mockNewsRepostiory, _mockNewsletterRepostiory, "fa");
        // Act
        ViewResult result = homeController.Index() as ViewResult;
        // Assert
        Assert.AreEqual("", result.ViewName);
    }

    [TestMethod]
    public void LatestNewsReturnsCorrectObject()
    {
        // Arrange
        HomeController homeController = new HomeController(_mockNewsRepostiory, _mockNewsletterRepostiory, "fa");
        // Act
        ViewResult result = homeController.LatestNews() as ViewResult;
        // Assert            
        Assert.IsNotNull(result.ViewData.Model, "Result model is not null.");
        Assert.IsTrue(_fakeNewsList.OrderByDescending(n => n.Date).SequenceEqual(result.ViewData.Model as IQueryable<News>), "Model is correct");
    }

    [TestMethod]
    public void LatestNewslettersReturnsCorrectObject()
    {
        // Arrange
        HomeController homeController = new HomeController(_mockNewsRepostiory, _mockNewsletterRepostiory, "fa");
        // Act
        ViewResult result = homeController.LatestNewsletters() as ViewResult;
        // Assert            
        Assert.IsNotNull(result.ViewData.Model, "Result model is not null.");
        Assert.IsTrue(_fakeNewsletterList.OrderByDescending(n => n.Date).SequenceEqual(result.ViewData.Model as IQueryable<Newsletter>), "Model is correct");
    }
}

首先,我真的需要测试这个构造函数吗?其次,将 _newsRepository 和其他人公开和只读然后在构造控制器后编写一个测试方法来检查他们的类型是一个好习惯吗?

4

1 回答 1

2

The only reason I'd recommend writing a test for the constructor is if you care a lot about getting as much code coverage as possible. Testing the fact that you can create an instance of the controller, and whether instances of each object created in the ctor are valid isn't a very valuable test. I'd say it's a waste of time.

So, for your first question I suggest you don't worry about unit testing the ctor. If there is a problem in the ctor then you will notice it very quickly via other unit tests, as explained in my next comment.

As for making the repository classes public and readonly, I don't recommend doing that. What you really need to focus on, regards unit tests, is functionality of the controller, especially methods that make use of the objects which are created in the ctor. That's where you need to concentrate on. Those tests will tell you whether or not these was an issue in the ctor for those objects.

于 2013-01-18T21:31:21.357 回答