Search code examples
c#asp.net-mvcmoqxunitsystem.diagnostics

Ignore Trace message when running Test


For a tracing purpose, I have to log every use of a method made by a user. I'm using System.Diagnostics.Trace to fill this purpose, but I'm encountering a problem when running test over these method.

Trace.TraceInformation($"L'utilisateur {HttpContext.Current.User.Identity.Name} a fait une recherche à partir de l'identifiant {ID} ");

This little code is working well on my application, but when it comes to testing, it's not working anymore (due to HttpContext.Current.User being undefined).

How can I potentially mock this or just tell my xUnit to ignore the trace while testing?


Solution

  • I would recommend that you hide your tracing logic behind an interface which can be mocked out.

    For example, you could declare an interface as below:

    public interface ITraceWriter
    {
        void TraceInfo(string traceText);
    }
    

    The next step would be to implement this interface as a tracing behaviour:

    public class UserTraceWriter : ITraceWriter
    {
        public void TraceInfo(string traceText)
        {
            Trace.TraceInformation($"User {HttpContext.Current.User.Identity.Name} {traceText}");
        }
    }
    

    You would need to inject the ITraceWriter into your class responsible for performing user actions, for example:

    public class UserDoSomethingClass
    {
        private readonly ITraceWriter writer;
    
        public UserDoSomethingClass(ITraceWriter writer)
        {
            this.writer = writer;
        }
    
        public void DoSomething()
        {
            // the user did something.
    
            this.writer.TraceInfo("did something");
        }
    }
    

    Finally, this would enable you to safely test the class:

     var mockTraceWriter = new Mock<ITraceWriter>();
    
     mockTraceWriter.Setup(w => w.TraceInfo(It.IsAny<string>()));
    
     var testClass = new UserDoSomethingClass(mockTraceWriter.Object);
    
     testClass.DoSomething();