Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to test combining both TestServer and moq Mock to replace methods in classes in ConfigureTestServices?

I am able to do integration tests using TestServer, and I can manually mock methods in any DI injected class by replacing in ConfigureTestServices the class by a mocking one as follows :

var webHostBuilder =
    new WebHostBuilder()
        .UseEnvironment("Testing")
        .UseContentRoot(projectDir)
        .ConfigureTestServices(s =>
        {
            s.TryAddTransient(IMyClass, MyMockMyClass);
        })
        .UseStartup<Startup>();

Where MyMockMyClass is a remplacement of MyClass, with the purpose of replacing a method (eg: Method1).

Is there an option to use a moq Mock.Of<MyClass> to quickly replace on the fly my Method1, without the need to create a new class MyMockMyClass? Something like :

var mymock = Mock.Of<IMyClass>();
Mock.Get(mymock ).Setup(m => m.Method1(It.IsAny<string>()).Returns(value: whatever);

And then somehow using this mymock with the line s.TryAddTransient(IMyClass, ... in the ConfigureTestServices code above?

like image 607
Yahia Avatar asked Jan 11 '19 13:01

Yahia


People also ask

Can integration tests replace unit tests?

Unit testing and integration testing are both important parts of successful software development. Although they serve different yet related purposes, one cannot replace the other.

How are integration tests implemented differently from unit tests?

Unit Testing is a kind of white box testing, whereas Integration Testing is a kind of black-box testing. For Unit Testing, accessibility of code is required, as it tests the written code, while for Integration Testing, access to code is not required, since it tests the interactions and interfaces between modules.

What is WebApplicationFactory?

WebApplicationFactory<TEntryPoint> is used to create a TestServer for the integration tests. TEntryPoint is the entry point class of the SUT, usually Program.


1 Answers

Have the factory delegate return the mocked services when configuring the test server

var mymock = Mock.Of<IMyClass>();
Mock.Get(mymock)
    .Setup(m => m.Method1(It.IsAny<string>())
    .Returns(value: whatever);

var webHostBuilder =
    new WebHostBuilder()
        .UseEnvironment("Testing")
        .UseContentRoot(projectDir)
        .ConfigureTestServices(services => {
            services.RemoveAll<IMyClass>();//Remove previous registration(s) of this service
            services.TryAddTransient<IMyClass>(sp => mymock);
        })
        .UseStartup<Startup>();

If you need a new mocked instance per call then move the logic into the factory delegate

like image 170
Nkosi Avatar answered Sep 21 '22 17:09

Nkosi