What should be the strategy of unit testing when using IoC?

后端 未结 4 1755
说谎
说谎 2021-02-12 23:29

After all what I have read about Dependency Injection and IoC I have decided to try to use Windsor Container within our application (it\'s a 50K LOC multi-layer web app, so I ho

相关标签:
4条回答
  • 2021-02-13 00:04

    I'm working on an ASP.NET MVC project with about 400 unit tests. I am using Ninject for dependency injection and MBUnit for testing.

    Ninject is not really necessary for unit testing, but it reduces the amount of code I have to type. I only have to specify once (per project) how my interfaces should be instantiated as opposed to doing this every time I initialize the class being tested.

    In order to save time on writing new tests, I have created test fixture base classes with as much generic setup code as possible. The setup procedures in those classes intialize fake repositories, create some test data and a fake identity for the test user. Unit tests only initialize data that is too specific to go into generic setup procedures.

    I am also mocking objects (as opposed to faking) in some tests, but I found that faking data repositories results in less work and more accurate tests.

    For example, it would be more difficult to check if the method under test I properly commits all updates to the repository after making them when using a repository mock than when I am using a repository fake.

    It was quite a bit of work to set up at the beginning, but really helped me reduce save a lot of time in the long run.

    0 讨论(0)
  • 2021-02-13 00:09

    You don't need DI container in unit tests because dependencies are provided through mock objects generated with frameworks such as Rhino Mocks or Moq. So for example when you are testing a class that has a dependency on some interface this dependency is usually provided through constructor injection.

    public class SomeClassToTest
    {
        private readonly ISomeDependentObject _dep;
        public SomeClassToTest(ISomeDependentObject dep)
        {
            _dep = dep;
        }
    
        public int SomeMethodToTest()
        {
            return _dep.Method1() + _dep.Method2();
        }
    }
    

    In your application you will use a DI framework to pass some real implementation of ISomeDependentObject in the constructor which could itself have dependencies on other objects while in a unit test you create a mock object because you only want to test this class in isolation. Example with Rhino Mocks:

    [TestMethod]
    public void SomeClassToTest_SomeMethodToTest()
    {
        // arrange
        var depStub = MockRepository.CreateStub<ISomeDependentObject>();
        var sut = new SomeClassToTest(depStub);
        depStub.Stub(x => x.Method1()).Return(1);
        depStub.Stub(x => x.Method2()).Return(2);
    
        // act
        var actual = sut.SomeMethodToTest();
    
        // assert
        Assert.AreEqual(3, actual);
    }
    
    0 讨论(0)
  • 2021-02-13 00:10

    As Darin has already pointed out, you don't need to use DI if you have mocks. (However, DI has a few other benefits as well, including, first of all, lessening dependencies in your code, which makes your code much easier to maintain and extend in the long run.)

    I personally prefer wiring up everything in my unit tests, thus relying as little as possible on external frameworks, config files etc.

    0 讨论(0)
  • 2021-02-13 00:11

    I've just written a very similar style and size app. I wouldn't put any dependency injection in the unit tests because it is not complicated enough to be necessary. You should use a mocking framework to create your mocks (RhinoMocks / Moq).

    Also Automocking in Moq or the Auto Mock Container in Rhinomocks will simplify building your mocks further.

    Auto mocking allows you to get object of the type you want to test without setting up mocks by hand. All dependencies are mocked automatically (assuming they are interfaces) and injected into the type constructor. If you need to you can set up expected behavior, but you don't have to.

    0 讨论(0)
提交回复
热议问题