开发者

ASP.NET MVC 2 Unit Testing Stange Errors

开发者 https://www.devze.com 2023-01-11 17:03 出处:网络
I am working through the book Professional ASP.NET MVC 2 and I am trying to get the unit testing in chapter 1 to work correctly; howver, I am getting some very strange errors.

I am working through the book Professional ASP.NET MVC 2 and I am trying to get the unit testing in chapter 1 to work correctly; howver, I am getting some very strange errors.

T开发者_JS百科here are two projects in the solution: NerdDinner, and NerdDinner.Tests.

In the NerdDinner Project I have the following interface:

IDinnerRepository.cs

//...
namespace NerdDinner.Models
{
     interface IDinnerRepository
     {
     //...
     }
}

Also in the NerdDinner project, I have the following class:

//...
using NerdDinner.Models;
//...
namespace NerdDinner.Controllers
{
     public class DinnersController : Controller
     {
     IDinnerRepository dinnerRepository;
     // Default constructor
     public DinnersController() : this(new DinnerRepository()){} // DinnerRepository is another concrete implementation of IDinnerRepository
     //Test constructor
     public DinnersController(IDinnerRepository repository) {
     dinnerRepository = repository;
     }
     }
}

In the NerdDinner.Tests project, I have the following concrete implementation of IDinnerRepository:

//...
using NerdDinner.Models;
//...
namespace NerdDinner.Tests.Fakes
{
     class FakeDinnerRepository : IDinnerRepository
     {
     //...
          public FakeDinnerRepository(List<Dinner> dinners)
          {
          //...
          }
     //...
     }
}

Now for the actual unit test (in NerdDinner.Tests)

using NerdDinner.Controllers;
//...
using NerdDinner.Models;
using NerdDinner.Tests.Fakes;
namespace NerdDinner.Tests
{
     [TestClass]
     public class DinnersControllerTest
     {
          List<Dinner> CreateTestDinners()
          {
          //...
          }
          DinnersController CreateDinnersController()
          {
          return new DinnersController(new FakeDinnerRepository(CreateTestDinners()));
          }
     }
}

And now for the actual problem: In the method CreateDinnersController in the class DinnerControllerClass, I am getting the following error:

DinnersController.DinnersController(NerdDinner.Models.IDinnerRepository repository) (+ 1 overload(s)) Error: The best overloaded method match for 'NerdDinner.Controllers.DinnersController.DinnersController(NerdDinner.Models.IDinnerRepository)' has some invalid arguments.

It gives me the option to create a constructor stub in DinnersController. It generates the following code:

private global::NerdDinner.Tests.Fakes.FakeDinnerRepository repository;
//...
public DinnersController(global::NerdDinner.Tests.Fakes.FakeDinnerRepository repository)
{
     // TODO: Complete member initialization
     this.repository = repository;
}

Even after generating that code, I still get the same error. But why should I even need that code anyway? As far as I can tell, I am doing everything correctly.

Can anybody help me figure out what is going on here?

Edit The generated code is giving the following error:

The type or namespace 'Tests' does not exist in the namespace 'NerdDinner' (are you missing any assembly reference?)


From what you've shown the IDinnerRepository interface is not public meaning that it is not visible from your unit test. I would recommend you making it public as I suspect you have two different interfaces : one defined in the unit test and one in your project which conflict. Also I would recommend you to avoid relying on Visual Studio generate all the crap reflection code in order to test private and internal members.


The last error you're getting is due to there being no reference from the production code to the test code - but that's appropriate. You don't want that extra constructor.

Instead, you need to find out why the existing constructor taking an IDinnerRepository isn't being used. Are you sure you only have one interface called IDinnerRepository? If you go to the FakeDinnerRepository source, go to the declaration, put the cursor in IDinnerRepository and hit F12 (go to definition) does it go to the right place?

If you add a new member to IDinnerRepository (just for the sake of testing: void Foo(); would be fine) does it cause both the production and fake implementation to fail to compile?

0

精彩评论

暂无评论...
验证码 换一张
取 消