I have a class which inherits from WebClient - in some code I am trying to test there is the usual:
using(var client = new SomeWebClient()){...}
Now I don't want to use that SomeWebClient class in my tests so I'd like to inject in some kind of stub.
Without using the servicelocator pattern what are my options? I can't use any real IoC as this assembly is used by multiple platforms both mobile and full .NET
I'm sure the answer is staring me in the face but I think I'm having "one of those days"!
1) Use an interface
using(ISomeWebClientc = new SomeWebClient()){...}
2a) Create a factory that returns an ISomeWebClient implementation.
3) Let it return your correct class in the production code or let it create a stub in your tests.
2b) Alternatively, just pass an ISomeWebClient to your class or method and initialize it differently in your test or production code.
You can inject a Func<TResult>. This Func is then called in your using statement, like so:
using (ISomeClient client = InjectedFunc())
{
...
}
public delegate Func<ISomeClient> InjectedFunc();
...
Then somewhere in your code you assign this Func a value, which is a code block to be executed later:
InjectedFunc = delegate(){ return new MyImplementation(); };
// or some other way of creating a new instance, as long as
// you return a fresh one
and so, this is functionally the same as if your using block would say:
using (ISomeClient client = new MyImplementation())
{
...
}
Related
I have a class Library project which will be consumed by some legacy code and some modernized code. briefly I would like to show what issues I am facing with.
class ClasslibraryService
{
private Dependency1 _dependency1;
private Dependency2 _dependency2
public ClasslibraryService(Dependency1 dependency)
{
_dependency1 = dependency;
// this dependency2 could be something like logger or Bearer token service which I do not want to expose to consuming application
_dependency2 = new Dependency2(new Dependency3());
}
public int DoSomeOperation()
{
var res = _dependency2.DoSomething();
return _dependency1.DoSomeOperation(res);
}
}
So basically I had to new up within constructor without injecting dependency using constructor.
Now while unit test this class , I have created another constructor which takes all dependency through constructor. This is working fine.
But question here is
I know I am violating main objective of unit testing by creating another constructor.Actual code will not be using this constructor. But I could not find any other way too!!
If 1 is not correct solution , please suggest me one solution
TIA
I know I am violating main objective of unit testing by creating
another constructor.Actual code will not be using this constructor.
But I could not find any other way too!!
I know this is heresy for some but I believe there's no hard rule in software development. It's a game of tradeoffs. If it's too expensive to change how your constructor works, you can probably do something like this for now:
public ClasslibraryService(Dependency1 dependency1, Dependency2 dependency2 = null)
{
_dependency1 = dependency1;
_dependency2 = dependency2 ?? new Dependency2(new Dependency3());
}
This introduces a default implementation for real code which can be overridden in unit tests. You can then revisit this code later and make it purer.
How to replicate this code with Autofac syntax?
public static class MenuConfig
{
public static void Initialize()
{
var _menuService = DependecyFactory.GetInstance<IMenuService>();
Parameters.Menu = _menuService.Menu();
}
}
Before calling this a "duplicate question" please note that I'm looking for an Autofac command. I CANNOT inject the interface anywhere and then call "Resolve". What I need to is perform an "InstancePerRequest" inline and uninjected so I don't have to do this:
var _service = new Service(new Dependency(new context()));
LightInject has a method that allows instantiation from an interface OUTSIDE of a constructor like this:
var _service = DependecyFactory.GetInstance<IService>();
What is the equivalent method for Autofac?
When calling containerBuilder.Build() you get back a container which implements IContainer and ILifetimeScope, whenever you get hold of one of these interfaces, you can resolve types from it:
container.Resolve<IService>();
If you want this container to be static, you could add the container as a static property to the Program or Startup class (depending if you're creating a Console or ASP.NET application).
Remember that the root container will be around for the entire duration of your application, so this can result in unwanted memory leaks when used incorrectly. Also see the warning in the documentation.
Still, it's perfectly possible to do the memory management yourself by resolving an Owned<> version from your interface:
using (var service = Program.Container.Resolve<Owned<IService>>())
{
service.Value.UseService();
}
Anyway, since you mention a static class in the comments, the best solution is to change that into a non-static class and register it as a singleton with Autofac. Then you can inject a Func<Owned<IService>> serviceFactory into that singleton and create/dispose an instance of the service wherever you need it.
using (var service = serviceFactory())
{
service.Value.UseService();
}
This is simply not possible with Autofac. All other solutions involving Autofac will require code refactoring which may potentially break software functionality. So unfortunately, the most elegant and least disruptive solution is this:
var _service = new Service(new Dependency(new context()));
Since this is an edge case addressing only one part of the software, this compromise is acceptable. It would be nice, however, if Autofac implemented this functionality in some future release.
I am attempting to setup a simple unit test for my code. I have an interface and implementation that talks to an external service via WCF. I am attempting to mock this with the code below;
private Mock<IPayments> _mockIPayments;
_mockIPayments.Setup(x => x.GetCreditCard(It.IsAny<GetCreditCardRequest>())).Returns(getCreditCardResponse);
In the unit test itself, I create an instance of the service that would ultimately call the WCF service;
var paymentService = new PaymentService();
var response = paymentService.GetCardDetails(cardId);
Within the PaymentService itself, the code;
var response = ServiceInvoker.Invoke<IPayments, GetCreditCardRequest, GetCreditCardResponse>
(
"Payments",
request,
(proxy, req) => proxy.GetCreditCard(req));
(Note that ServiceInvoker.Invoke is just a wrapper to create a channel and process the request)
Am I missing something, should the mock setup not be catching the request to GetCreditCard?
ETA
To make it a little clearer, the flow is;
UnitTest -> PaymentsService -> IPayments
You need to pass your mocked instance to the service somehow.
var paymentService = new PaymentService(_mockIPayments.Object);
Simply specifying a setup will not let Moq replace all instances of some interface with the what you specified. It simply defines what Moq will return when a certain Mock instance will be called. In your case _mockIPayments.
You then have to use that mocked IPayments instance in your code (either pass it in a constructor or method) for your code to actually use it.
If your PaymentService is currently creating an IPayments object internally, to use mocking you will have to use something like Dependency Injection so that you are able to specify the IPayments instance externally and thus supply a mock instance in your tests.
Likewise:
var paymentService = new PaymentService(_mockIPayments.Object);
I've got a controller with a lot of constructor injection:
public MoviesController(ISession session, IClientContext clientContext, PManager pManager, ISegmentationService segmentationService, IGeoLocator geoLocator, IBus bus)
{
_session = session;
_clientContext = clientContext;
_pManager = pManager;
_segmentationService = segmentationService;
_geoLocator = geoLocator;
_bus = bus;
}
From my understanding (just read about Mocking), I've got a lot of Mock object properties to manually set if I wish to make a comprehensive test suite based on this controller.
For one method I'm only using one service (I'd even like to automate that with little effort if possible):
public object Show(Guid id)
{
var movie = _session.Get<movie>(id);
return movie;
}
But in another there are many services being used - is there any way to set those Moq objects up quickly? I could really use some examples as I'm new to testing. It's an asp.net mvc project with webapi 1 bundled in (testing the webapi controller here)
As has been said in the comments, if you have common setup code, you can put it in a Setup method that is called automatically from your testing framework before each test. It's decorated with a Setup attribute if you're using Nunit TestInitialize if you're using MStest. If you're using XUnit then it's a bit different.
So, your class might look like this:
public class SomeTests {
Mock<ISession> _sessionMock;
Mock<IClientContext> _clientContextMock;
[Setup]
public void Setup() {
_sessionMock = new Mock<ISession>();
_clientContextMock = new Mock <IClientContext();
}
MovieController CreateSut() {
return new MovieController(_sessionMock.Object, _clientContextMock.Object, ...);
}
[Test]
public void TestSomething() {
_sessionMock.Setup(x=>...);
//...
var sut = CreateSut();
//...
}
}
If you're trying to get away from completely creating the mocks manually, then you might want to look at something like AutoFixture with AutoMoq. Which will automatically supply mock instances when creating objects that accept interfaces. AutoFixture can be quite useful, but there is a learning curve to using it effectively so you might want to look at a tutorial / quickstart.
You could also configure an IOC container to supply mock instances for your test project, although I've never gone down that route myself.
For your example, you only need to mock the session, and can leave all the other dependencies null, since their behaviour should be irrelevant to the behaviour you are testing:
Mock<ISession> mockSession = new Mock<ISesssion>();
MoviesController controller = new MoviesController(mockSession.Object, null,null,null,null,null);
There is no need for you to set up any mocks other than the ones you need for this particular test
I am new to both MOQ and TDD / Unit Testing. I find myself repeating a lot of the same code in my "Arrange" section of each test method and it seems there really ought to be a better way.
First the code that get's oft repeated:
#region Arrange
#region create my Mock Objects
var serviceMock = new Mock<IOrganizationService>();
var factoryMock = new Mock<IOrganizationServiceFactory>();
var tracingServiceMock = new Mock<ITracingService>();
var notificationServiceMock = new Mock<IServiceEndpointNotificationService>();
var pluginContextMock = new Mock<IPluginExecutionContext>();
var serviceProviderMock = new Mock<IServiceProvider>();
#endregion
#region Authentication Stuff
var organizationUri = "http://.../XRMServices/2011/Organization.svc";
var orgServiceManagement = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(organizationUri));
var credentials = new AuthenticationCredentials();
var username = "USER_ID";
var password = "USER_PWD";
var domain = "MyDomain";
credentials.ClientCredentials. Windows.ClientCredential = new NetworkCredential(username, password, domain);
IOrganizationService service = new OrganizationServiceProxy(orgServiceManagement, credentials.ClientCredentials);
#endregion
#endregion
I considered making custom snippets, constants, etc. but that would not really save the repetitious code just save me some time typing.
Next I thought about scoping everything above at the class level...but some warning bells went off...If the class instantiates once for all test methods then could there be the possibility of variable pollution? Given in the small sample here it really wouldn't happen but I'm trying to think ahead / develop good practices and habits.
What about creating a "Mock & Authentication" object that had all these defined in that object. Then I could have several of these objects with different credentials and my test methods could reference / use just the one variation needed?
So what would be your advice / recommendations for applying some DRY principles to my test cases.
First, your setup is really large. If this is an unit test, this calls for refactoring. Are you sure your components under test do one thing and one thing only? Judging by the names of dependencies, I would assume no.
Next I thought about scoping everything above at the class level...but some warning bells went off...If the class instantiates once for all test methods then could there be the possibility of variable pollution?
No, most test runners create test class instance per test run and unit test frameworks usually allow sort of before test setup, a piece of code (usually method or constructor) that does just this.
In NUnit you got [SetUp] attribute (MS Test uses [TestInitialize] while xUnit uses class constructor):
[SetUp]
public void InitializeDependencies()
{
serviceMock = new Mock<IOrganizationService>();
// ...
}
This is how you usually solve this kind of problems.
What about creating a "Mock & Authentication" object that had all these defined in that object.
While this might be a good idea for authentication part, it certainly is not as sound for mocks. The fact you even consider it rings the refactoring bells once again.