I've classes similar to this:
public class Class1
{
private readonly IClient _client;
public Class1(Configuration config, CacheManager cacheManager)
{
_client = new Client(config, cacheManager);
}
protected async Task<T> PostAndDeserialize<T>(string param1, object param2)
{
var result = await _client.PostSomething(param1, param2);
return JsonConvert.DeserializeObject<T>(await result.Content.ReadAsStringAsync());
}
}
public class Class2 : Class1
{
public Class2(Configuration config, CacheManager cacheManager) : base(config, cacheManager)
{
}
public async Task<Response> CreateSomething(Request request)
{
//do something
var result = PostAndDeserialize<Result>("test", test);
return new Response { Id = result.Id };
}
}
I need to write unit test for Class2, CreateSomething method - how do I mock PostAndDeserialize method ? I've tried and find a way to mock protected generic class from base class but I couldn't find any help with it :( Or maybe it should be done in some other way ?(I'm new to unit test). Any help is appreciated.
I've tried using Protected() and calling method by it's name but as it's generic method it didn't work.
Your options are:
Rewrite the code so it is testable. This can be done by making the method virtual or by using composition instead of inheritance and program to an interface instead of an implementation.
Purchase Visual Studio Enterprise which includes Microsoft Fakes. Or some other third-party solution.
Related
I have a IData interface that handles the SQL data access logic and as well as retrieving data from SQL Server:
public interface IData
{
Task<IEnumerable<string>> GetUsers();
}
I have a Emailer class that sends an email with the list of Users and currently I am injecting IData via the constructor and accessing the GetUsers() method within another Method of the Emailer class:
public class Emailer
{
private readonly IData _data;
public Emailer(IData data)
{
_data = data;
}
public async Task Send()
{
var users = await _data.GetUser(); // access data here
}
}
In an act to try and refactor this code and apply the Single Responsibility principle, I want to abstract away the GetUser() logic into its own seperate class however how can I do this without having to initialise IData in the constructor of the new class to avoid having to pass the IData object as a parameter when newing up the class?
Example:
public class UserData
{
private readonly IData _data;
public UserData(IData data)
{
_data = data; // not ideal as I'd have to pass the object from the Emailer class and other classes that call Emailer
}
public async Task Fetch()
{
var users = await _data.GetUser(); // access data here
}
public async Task ManipulateUser(){} // example of future extensibility hence the reason for a seperate class
}
Could implementing a factory pattern to solve this problem (if yes, how?) or any other ideas?
TIA
Compare interfaces to black boxes. They do stuff, but you have no idea of how they do it.
But, if you look at the interface name and have no idea of what they are doing, you got it wrong.
In this case, IData seems like a database god object. Am I correct? Does it handle all your SQL operations? If so, divide it into different interfaces which all have a clear responsibility. "I handle DB access for user objects" = IUserData.
Regarding methods, C# is an object-oriented language, and classes (and interfaces) are the primary way of letting objects communicate. You won't get any benefits in this case if you try to inject methods instead.
Update
Do not refractor code to remove dependencies. composition makes the code more robust. Instead, use a Inversion Of Control container to create your classes.
Read this article to get started: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-6.0
Can't you just abstact bind UserData to an interface, called IUserData and inject that into your Emailer class if needed?
I'm on my mobile right now but if you like I can post a code example later if you don't understand.
--UPDATE--
Here is the updated code.
//Refactor your existing classes to look like this.
public interface IData
{
Task<IEnumerable<string>> GetUsers();
}
public interface IEmailer
{
Task Send();
}
public class Emailer : IEmailer
{
private readonly IUserData _userData;
public Emailer(IUserData userData)
{
_userData = userData;
}
public async Task Send()
{
var users = await _userData.Fetch(); // access data here
}
}
public interface IUserData
{
Task Fetch();
Task ManipulateUser();
}
public class UserData : IUserData
{
private readonly IData _data;
public UserData(IData data)
{
_data = data;
}
public async Task Fetch()
{
var users = await _data.GetUser();
}
public async Task ManipulateUser() { }
}
//Example of class calling Emailer
public interface IRandomClass
{
Task RunSomeCode();
}
public class RandomClass : IRandomClass
{
private readonly IEmailer _emailer;
public RandomClass(IEmailer emailer)
{
_emailer = emailer;
}
public async Task RunSomeCode()
{
//Example code
await _emailer.Send();
}
}
Binding the dependencies (assuming you're using .netcore)
services.AddScoped<IUserData, UserData>();
services.AddScoped<IEmailer, Emailer>();
services.AddScoped<IRandomClass, RandomClass>();
This should give you a good baseline to work from.
Let me know if you need anything else.
Happy coding!
You seem to redesign a class prematurely violating the YAGNI principle. If you aren't extending UserData right now, there is no need to introduce a further abstraction that does nothing more than the code already did.
When you do have extra responsibilities then you will create the UserData object passing IData into its constructor. Then you pass the UserData instance into the Emailer constructor. You basically switch one object for another.
IData seems too generic for this use case. You can instead introduce IUserData
which would be only responsible for handling data access for the User.
Then your setup will look like this:
public interface IUserData
{
Task<IEnumerable<string>> GetUsers();
}
public class UserData: IUserData
{
public async Task<IEnumerable<string>> GetUsers()
{ ... }
}
public interface IEmailer
{
Task Send();
}
public class Emailer : IEmailer
{
private readonly IUserData _userData;
public Emailer(IUserData userData)
{
_userData = userData;
}
public async Task Send()
{
var users = await _userdata.GetUser();
}
}
Alternatively, you can have 3 layers with a generic Data class in charge of all the data access operations and have the UserData class fine-grain it. This of course depends on how large and unmanageable can this data service become. I personally prefer to have tailor-made services for each data access use case.
I have the following interfaces and service implemented like this:
public interface IParentInterface<T> where T : class
{
T GetParent(T something);
}
public interface IChildInterface : IParentInterface<string>
{
string GetChild();
}
public class MyService
{
private readonly IChildInterface _childInterface;
public MyService(IChildInterface childInterface)
{
_childInterface = childInterface;
}
public string DoWork()
{
return _childInterface.GetParent("it works");
}
}
Here is my test for the DoWork method of MyService class:
Create a new mock object of the child interface
Setup the GetParent method of the parent interface
Pass the mock object to the service constructor
Execute the DoWork
Expect to have the resp = "It really works with something!" but it's null
[Fact]
public void Test1()
{
var mockInterface = new Mock<IChildInterface>();
mockInterface
.As<IParentInterface<string>>()
.Setup(r => r.GetParent("something"))
.Returns("It really works with something!");
var service = new MyService(mockInterface.Object);
string resp = service.DoWork(); // expects resp = "It really works with something!" but it's null
Assert.NotNull(resp);
}
Other info:
Moq 4.16.1
.NET CORE (.NET 5)
XUnit 2.4.1
Your mock setup is saying to mock the method with "something" is passed in. You should change that to match what the class is passing in, e.g. "it works" or much easier is to allow any string using It.IsAny<string>(). For example:
mockInterface
.As<IParentInterface<string>>()
.Setup(r => r.GetParent(It.IsAny<string>()))
.Returns("It really works with something!");
I am writing a test that depends on the results of an extension method but I don't want a future failure of that extension method to ever break this test. Mocking that result seemed the obvious choice but Moq doesn't seem to offer a way to override a static method (a requirement for an extension method). There is a similar idea with Moq.Protected and Moq.Stub, but they don't seem to offer anything for this scenario. Am I missing something or should I be going about this a different way?
Here is a trivial example that fails with the usual "Invalid expectation on a non-overridable member". This is a bad example of needing to mock an extension method, but it should do.
public class SomeType {
int Id { get; set; }
}
var ListMock = new Mock<List<SomeType>>();
ListMock.Expect(l => l.FirstOrDefault(st => st.Id == 5))
.Returns(new SomeType { Id = 5 });
As for any TypeMock junkies that might suggest I use Isolator instead: I appreciate the effort since it looks like TypeMock could do the job blindfolded and inebriated, but our budget isn't increasing any time soon.
Extension methods are just static methods in disguise. Mocking frameworks like Moq or Rhinomocks can only create mock instances of objects, this means mocking static methods is not possible.
If you can change the extension methods code then you can code it like this to be able to test:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
public static class MyExtensions
{
public static IMyImplementation Implementation = new MyImplementation();
public static string MyMethod(this object obj)
{
return Implementation.MyMethod(obj);
}
}
public interface IMyImplementation
{
string MyMethod(object obj);
}
public class MyImplementation : IMyImplementation
{
public string MyMethod(object obj)
{
return "Hello World!";
}
}
So the extention methods are only a wrapper around the implementation interface.
(You could use just the implementation class without extension methods which are sort of syntactic sugar.)
And you can mock the implementation interface and set it as implementation for the extensions class.
public class MyClassUsingExtensions
{
public string ReturnStringForObject(object obj)
{
return obj.MyMethod();
}
}
[TestClass]
public class MyTests
{
[TestMethod]
public void MyTest()
{
// Given:
//-------
var mockMyImplementation = new Mock<IMyImplementation>();
MyExtensions.Implementation = mockMyImplementation.Object;
var myClassUsingExtensions = new MyClassUsingExtensions();
// When:
//-------
var myObject = new Object();
myClassUsingExtensions.ReturnStringForObject(myObject);
//Then:
//-------
// This would fail because you cannot test for the extension method
//mockMyImplementation.Verify(m => m.MyMethod());
// This is success because you test for the mocked implementation interface
mockMyImplementation.Verify(m => m.MyMethod(myObject));
}
}
I know this question hasn't been active for about a year but Microsoft released a framework to handle exactly this called Moles.
Here are a few tutorials as well:
DimeCasts.net
Nikolai Tillman's Tutorial
I created a wrapper class for the extension methods that I needed to mock.
public static class MyExtensions
{
public static string MyExtension<T>(this T obj)
{
return "Hello World!";
}
}
public interface IExtensionMethodsWrapper
{
string MyExtension<T>(T myObj);
}
public class ExtensionMethodsWrapper : IExtensionMethodsWrapper
{
public string MyExtension<T>(T myObj)
{
return myObj.MyExtension();
}
}
Then you can mock the wrapper methods in your tests and code with your IOC container.
For extension methods I normally use the following approach:
public static class MyExtensions
{
public static Func<int,int, int> _doSumm = (x, y) => x + y;
public static int Summ(this int x, int y)
{
return _doSumm(x, y);
}
}
It allows to inject _doSumm fairly easy.
Best thing you can do is to provide a custom implementation for the type that has the extension method, e.g:
[Fact]
public class Tests
{
public void ShouldRunOk()
{
var service = new MyService(new FakeWebHostEnvironment());
// Service.DoStuff() internally calls the SomeExtensionFunction() on IWebHostEnvironment
// Here it works just fine as we provide a custom implementation of that interface
service.DoStuff().Should().NotBeNull();
}
}
public class FakeWebHostEnvironment : IWebHostEnvironment
{
/* IWebHostEnvironment implementation */
public bool SomeExtensionFunction()
{
return false;
}
}
I am writing a client wrapper around an external client that is defined in a NuGet package. The NuGet package contains below interface and the class.
public interface IServiceClient
{
Task<Job> CreateJobAsync(JobDetails jobdetails);
}
public class ServiceClient : IServiceClient, IDisposable
{
public async Task<Job> CreateJobAsync(JobDetails jobDetails)
{
// Some processing and returns a job that contains required response and status
return job;
}
}
In my application, I write a client wrapper around the service client as below:
public interface IServiceClientWrapper
{
Task<ResponseDto> PostAsync(RequestDto request);
}
public class ServiceClientWrapper : IServiceClientWrapper
{
private static IServiceClient serviceClient;
public static void Init()
{
// See below for defintion
serviceClient = ClientFactory.Create();
}
public async Task<ResponseDto> PostAsync(RequestDto request)
{
// Convert request to JobDetails as required
var job = await serviceClient.CreateJobAsync(jobDetails);
// Convert job to ResponseDto and return
return response;
}
// Since ServiceClient implements IDisposable
public static void Close()
{
if (serviceClient != null)
{
((ServiceClient)serviceClient).Dispose();
}
}
}
internal static class ClientFactory
{
public static IServiceClient ServiceClient { get; set; }
public static IServiceClient Create()
{
if (ServiceClient != null)
{
// Used during unit testing
return ServiceClient;
}
return new ServiceClient(APIBaseAddress, AccessKey);
}
}
Questions:
Since the interface isn't marked IDisposable, I introduce Init and Close methods to do that. Is there a better way to handle this?
Having the serviceClient as static, is it thread-safe since I always invoke the non-static CreateJobAsync method with new paramters for each request?
I'd suggest that IDisposable is a detail of the concrete implementation of IServiceClientWrapper i.e. ServiceClientWrapper
It is not necessarily apart of the IServiceClientWrapper, as you may in theory have implementations which don't need to dispose of anything.
So as the comments suggest, ServiceClientWrapper should implement IDisposable.
I'm using moq.dll
When I mock a class(all the IRepository interface) i use this line code
int state = 5;
var rep = new Mock<IRepository>();
rep.Setup(x => x.SaveState(state)).Returns(true);
IRepository repository = rep.Object;
but in this case i mock all the function in repository class.
Then all the methods in class repository are substituted with the methods setup of Mock dll
I want use all the methods defined in class repository(the real class) and mock only one function(SaveState)
How can I do this? Is possible?
You can create an instance of the real repository, then use the As<>() to obtain the desired interface, which you can then override with the setup, like this:
var mockRep = new Mock<RealRepository>(ctorArg1, ctorArg2, ...)
.As<IRepository>();
mockRep.Setup(x => x.SaveState(state)).Returns(true);
Then mockRep.Object as the repository dependency to the class under test.
Note that you will only be able to Mock methods on the Interface*, or virtual methods, in this way.
Update : *This might not work in all scenarios, since .Setup will only work on virtual methods, and C# interface implementations are "virtual" and sealed by default. And using As() will prevent the partial mock behaviour.
So it appears that the RealRepository concrete class will need to implement the IRepository interface with virtual methods in order for the partial mock to succeed, in which case CallBase can be used for the wire-up.
public interface IRepo
{
string Foo();
string Bar();
}
public class RealRepo : IRepo
{
public RealRepo(string p1, string p2) {Console.WriteLine("CTOR : {0} {1}", p1, p2); }
// ** These need to be virtual in order for the partial mock Setups
public virtual string Foo() { return "RealFoo"; }
public virtual string Bar() {return "RealBar"; }
}
public class Sut
{
private readonly IRepo _repo;
public Sut(IRepo repo) { _repo = repo; }
public void DoFooBar()
{
Console.WriteLine(_repo.Foo());
Console.WriteLine(_repo.Bar());
}
}
[TestFixture]
public class SomeFixture
{
[Test]
public void SomeTest()
{
var mockRepo = new Mock<RealRepo>("1st Param", "2nd Param");
// For the partially mocked methods
mockRepo.Setup(mr => mr.Foo())
.Returns("MockedFoo");
// To wireup the concrete class.
mockRepo.CallBase = true;
var sut = new Sut(mockRepo.Object);
sut.DoFooBar();
}
}
I came to this page because I had exactly the same problem: I needed to mock a single method, which was relying on many external sources and could produce one of three outputs, while letting the rest of the class do its work. Unfortunately the partial mock approach proposed above did not work. I really don't know why it did not work. However, the main problem is that you can't debug inside such mocked class even if you put break points where you want. This is not good because you might really need to debug something.
So, I used a much simpler solution: Declare all methods that you want to mock as virtual. Then inherit from that class and write one-liner mock overrides to return what you want, for example:
public class Repository
{
/// <summary>
/// Let's say that SaveState can return true / false OR throw some exception.
/// </summary>
public virtual bool SaveState(int state)
{
// Do some complicated stuff that you don't care about but want to mock.
var result = false;
return result;
}
public void DoSomething()
{
// Do something useful here and assign a state.
var state = 0;
var result = SaveState(state);
// Do something useful with the result here.
}
}
public class MockedRepositoryWithReturnFalse : Repository
{
public override bool SaveState(int state) => false;
}
public class MockedRepositoryWithReturnTrue : Repository
{
public override bool SaveState(int state) => true;
}
public class MockedRepositoryWithThrow : Repository
{
public override bool SaveState(int state) =>
throw new InvalidOperationException("Some invalid operation...");
}
That's all. You can then use your mocked repos during unit tests AND you can debug anything you need. You can even leave the protection level below public so that not to expose what you don't want to expose.