2017-10-02 1 views
3

내 로거가 예외를 올바르게 로깅하고 있는지 확인할 수 있도록 예외 처리와 관련된 단위 테스트를 작성하려고합니다.NS 대체 ILogger .NET 코어

[Fact] 
public void LogsExcpetionWhenErrorOccursInCreate() 
{ 
    var newUser = new UserDataModel 
    { 
     FirstName = "Rick", 
     MiddleName = "Jason", 
     LastName = "Grimes", 
     Email = "[email protected]", 
     Created = new DateTime(2007, 8, 15) 
    }; 
    var exception = new Exception("Test Exception"); 
    // configure InsertOne to throw a generic excpetion 
    _mongoContext.InsertOne(newUser).Returns(x => { throw exception; }); 

    try 
    { 
     _collection.Create(newUser); 
    } 
    catch 
    { 
     // validate that the logger logs the exception as an error 
     _logger.Received().LogError(exception.Message); 
    } 
} 

는 다음과 같은 방법 로깅 테스트 할 : 나는 내 테스트는 다음을 가지고 조롱 프레임 워크와 Microsoft.Extensions.Logging.ILogger로 NSubstitute을 사용하고

public UserDataModel Create(UserDataModel user) 
{ 
    try 
    { 
      return MongoContext.InsertOne(user);     
    } 
    catch(Exception e) 
    { 
      _logger?.LogError(e.Message); 
      throw new DataAccessException("An error occurred while attempting to create a user.", e); 
     } 

을}

내 테스트 실패 다음 오류 :

Message: NSubstitute.Exceptions.ReceivedCallsException : Expected to receive a call matching: 
    Log<Object>(Error, 0, Test Exception, <null>, Func<Object, Exception, String>) 
Actually received no matching calls. 
Received 1 non-matching call (non-matching arguments indicated with '*' characters): 
    Log<Object>(Error, 0, *Test Exception*, <null>, Func<Object, Exception, String>) 

왜 이것이 실패하는지 잘 모르겠습니다. 왜냐하면 심지어 오류 메시지에서도 호출이 동일하기 때문입니다.

미리 감사드립니다.

public UserCollectionTest() 
{ 
    _mongoContext = Substitute.For<IMongoContext<UserDataModel>>(); 
    _logger = Substitute.For<ILogger>(); 
    // create UserCollection with our mock client 
    _collection = new UserCollection(_mongoContext, _logger); 
} 
+0

ILogger 대체품을 만들고 주입하는 방법을 명확히하십시오. –

+0

테스트 생성자가있는 게시물을 업데이트했습니다. 여기에서 하위를 삽입하고 있습니다. –

답변

3

LogError 당신이 있는지 확인하려고 그렇게하면 ILogger입니다 방법되지 않습니다 :

는 업데이트 : 로거 모의를 주입하고 여기 어디에

시험의 생성자입니다입니다 메서드는 NSubstitute가 어떻게 든 그것을 처리하려고하는 특정 매개 변수로 호출되었습니다 (정확히 어떻게 알지 못합니다) 실패합니다.

LogError 확장 방법의 코드는 다음과 같습니다

public static void LogError(this ILogger logger, string message, params object[] args) 
{ 
    if (logger == null) 
    throw new ArgumentNullException("logger"); 
    logger.Log<object>(LogLevel.Error, (EventId) 0, (object) new FormattedLogValues(message, args), (Exception) null, LoggerExtensions._messageFormatter); 
} 

그래서 당신이 로그 메소드가 호출되었는지 확인해야합니다.

나는 약간의 예를 단순화했습니다. 나는 아이디어가 분명해야한다고 생각한다.

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     var logger = Substitute.For<ILogger>(); 
     try 
     { 
      Create(logger); 
     } 
     catch 
     { 
      logger.CheckErrorMessage("My Message"); 
     } 
    } 

    public string Create(ILogger logger) 
    { 
     try 
     { 
      throw new Exception("My Message"); 
     } 
     catch (Exception e) 
     { 
      logger?.LogError(e.Message); 
      throw new Exception("An error occurred while attempting to create a user.", e); 
     } 
    } 
} 

public static class TestExtensions 
{ 
    public static void CheckErrorMessage(this ILogger logger, string message) 
    { 
     logger.Received().Log(
      LogLevel.Error, 
      Arg.Any<EventId>(), 
      Arg.Is<object>(o => o.ToString() == message), 
      null, 
      Arg.Any<Func<object, Exception, string>>()); 
    } 
}