Simple Injector, can't override existing registration

后端 未结 1 1569

I am currently using Simple Injector for the first time. In my .NET project I am running test and mocking data returned from a web service and registering the object to the

相关标签:
1条回答
  • 2021-01-02 22:27

    Replacing an existing registration after you already worked with the container hardly ever has the behavior you would expect (and this holds for all DI libraries) and that's the reason why the Simple Injector container is locked. This is described in more details here (as @qujck already pointed out).

    First of all, if you are writing unit tests, you shouldn't use a container at all. Your unit tests should create the class under test themselves, or you extract this logic to a convenient factory method, such as:

    private static MailNotifier CreateMailNotifier(
        IDeposit deposit = null, ISendMail mailSender = null, ILog logger = null)
    {
      return new MailNotifier(
          deposit ?? Substitute.For<IDeposit>(),
          mailSender ?? Substitute.For<ISendMail>(),
          logger ?? Substitute.For<ILog>());
    }
    

    This factory method is a variation to the Test Data Builder pattern.

    By making use of optional parameters, it allows the unit test to specify only the fake implementation it requires during testing:

    public void Notify_WithValidUser_LogsAMessage()
    {
        // Arrange
        var user = new User();
    
        var logger = new FakeLogger();
    
        MailNotifier sut = CreateMailNotifier(logger: logger);
    
        // Act
        sut.Notify(user);
    
        // Assert
        Assert.AreEqual(expected: 1, actual: logger.LoggedMessages.Count);
    }
    

    If you use a container, because creating the class under test by hand is too cumbersome, it indicates a problem in your class under test (most likely a Single Responsibility Principle violation). Prevent using tools to work around problems in your design; your code is speaking to you.

    For integration tests however, it is much more usual to use the container, but in that case you should simply create a new container for each integration test. This way you can add or replace the IWebServiceOrder without any problem.

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