Layout of objects without a setter

I use a third-party UserContext library that only has a bunch of {get;}

public static UserContext Current { get; }
public UserContact CurrentContact { get; }
public string UserContactName { get; }

In my code, it just returns CurrentUser like this:

void DoSomething(){
    UserContext Current = UserContext.Current; // 3rd party lib
}

I have no way to install a new fake unit for unit testing. So, to mock this in my code, I did the following:

Created a subclass that inherits from UserContext and overwrites the current property:

public class UserContextFake : UserContext
{
    public new UserContext Current { get; set; }
}

Then create an interface and a wrapper:

public class UserContextWrapper : IUserContext
{
    public UserContextWrapper()
    {
        userContext = UserContext.Current;
    }

    public UserContextWrapper(UserContext context)
    {
        userContext = context;
    }

    private readonly UserContext userContext;

    public UserContext Current
    {
        get { return userContext; }
    }
}

Now I can embed userContextWrapper in my classes. I disclose two constructors: one that uses UserContext.Current (third-party library) session material for production code, and one that can receive custom UserContextFake. In IoC, I map IUserContext to UserContext

: CurrentContact, , UserContext (UserContext.CurrentContact)

+4
1

3dr? lib. . , , , . ().

public interface IThirdPartyLibraryWrapper
{
    UserContext Current { get; }
    UserContact CurrentContact { get; }
    string UserContactName { get; }
}

public class ThirdPartyLibraryWrapper 
    : IThirdPartyLibraryWrapper
{
    public UserContext Current 
    { 
        get { /* return Current from third party library */}
    }

    public UserContact CurrentContact 
    { 
        get{ /* return CurrentContact from third party library */} 
    }

    public string UserContactName 
    { 
        get{ /* return UserContactName from third party library */} 
    }
}

public class ClassUnderTest
{
    // Inject 3rd party lib
    private IThirdPartyLibraryWrapper _library;
    public virtual IThirdPartyLibraryWrapper Library
    {
        get
        {
            if (_library == null)
                _library = new ThirdPartyLibraryWrapper();
            return _library;
        }
        set
        {
            if (value != null)
                _library = value;
        }
    }

    void DoSomething(){
        UserContext Current = Library.Current; 
    }
}

[TestMethod]
public void DoSomething_WhenCalled_UsesLibraryMock()
{
    // Arrange
    UserContext fakeUserContext = new UserContext();
    Mock<IThirdPartyLibraryWrapper> libraryMock = new Mock<IThirdPartyLibraryWrapper>();
    libraryMock.Setup(l => l.Current).Returns(fakeUserContext);
    ClassUnderTest cut = new ClassUnderTest();
    cut.Library = libraryMock.Object;

    // Act
    cut.DoSomething()

    // Assert
    // ...
}
+2

Source: https://habr.com/ru/post/1628004/


All Articles