Good day! I have an asp.net mvc application. In it, I try to create an architecture “by the mind” - with Dependency Injection, tests, and so on. In the application there are service classes in which business logic is concentrated. I need to cover these services with tests. Many services use a class of settings, instances of which are passed to them in constructors. For example:

public class AppSettings { public AppSettings() { SomeStr = WebConfigurationManager.AppSettings["str"]).ToString(); // и еще несколько подобных строк } public string SomeStr { get;set; } } public class MyService { public MyService(AppSettings settings) { _settings = settings; } private readonly AppSettings _settings; } 

The problem here is this. In the constructor of the AppSettings class, some variables are initialized, the data about which are obtained from the web.config file. It works in the code of the application itself, but if I try to test the MyService class in a separate test application, the problem arises: the class needs to pass an instance of AppSettings , but when creating it, an exception falls out because it is impossible to access the web.config . In addition, I don’t directly create the classes themselves; the DI library does this. How to be in this case and how to test MyService ? In addition, it seems to me a problem that the constructor of the AppSettings class AppSettings `web.config. Please tell me how to solve this problem? Thank you in advance.

  • And if the parameter from the web.config passed as a parameter necessary to create an instance of the class? those. something like public appSettings(string someStr){this.SomeStr = someStr;} - Bald
  • @Bald but how does this "tell" the DI library that creates instances of classes? - Pupkin
  • Well, in the di контейнере get the desired value from the config. - Bald
  • @Pupkin if for Ninject , then kernel.Bind<IAppSetting>().To<AppSetting>() .WithConstructorArgument(someStr, WebConfigurationManager.AppSettings["str"]).ToString()); - Vadim Prokopchuk

1 answer 1

If you use the AppSettings class as a settings class and IoC-контейнер , describe the IAppSettings interface and test it with Mock objects.

I will give an example. In the MyService class MyService you replace the settings argument of the constructor settings with IAppSetting . In the IoC-контейнере register the implementation. Suppose you use Ninject , then kernel.Bind<IAppSetting>().To<AppSetting>() . Then in the testing method you can customize your object.

 Mock<IAppSetting>() mock = new Mock<IAppSetting>(); mock.Setup(m => m.Field1).Returns(value1); MyService service = new MyService(mock.Object); 

Here you specify that when Field1 should return value1 .

Attention Field1 must be defined in the interface IAppSetting


An example is shown for Ninject