I've got a class that I'm trying to unit test but it uses a DaprClient object (from the SDK), which doesn't work in my unit test envioronment.
I would like to create a mock and use that instead but the only interface DaprClient implements is IDisposable.
Is there a way to mock DaprClient for unit tests?
The only solution I can think of would be to wrap DaprClient in a class with an interface and use this wrapper everywhere. This just feels really messy and will need the wrapper to be updated every time I want to use a new method on the DaprClient.
I'm open to other solutions which might bypass the problem but I'd prefer a simple replace with mock type approach.
I'm using .Net 5, xUnit and Moq in Visual Studio 2019 on Windows (although some team members use Macs so it needs to work on both platforms).
In this particular instance, I'm using the DaprClient.GetBulkSecretAsync method but I'd like a solution that I can use elsewhere, if possible.
You need to use one of two options
a mocking framework that uses shims as they make a mock object based on a concrete class. Fakes from visual studio enterprise and other paid frameworks have it. Fewer opensource frameworks have the option. Pose is one with the option perhaps via Shimmy
wrap the class in a class that uses a interface you can use for mocking (the worst possibility)
using Dapr.Client;
using FluentAssertions;
using Moq;
[TestMethod("How to mock GetBulkSecretAsync - 68362431")]
public async Task TestMethod1()
{
//arrange
var daprClient = new Mock<DaprClient>();
var exampleService = new ExampleService(daprClient.Object);
daprClient.Setup(d => d.GetBulkSecretAsync("my-store",
It.IsAny<IReadOnlyDictionary<string, string>>(),
It.IsAny<CancellationToken>()))
.ReturnsAsync(new Dictionary<string, Dictionary<string, string>>
{
{
"example",
new Dictionary<string, string>
{
{ "i don't understand the builk API (yet)", "some value" }
}
}
});
//act
var actual = await exampleService.GetBulkSecrets("my-store");
//assert
actual.Should().BeEquivalentTo(new Dictionary<string, Dictionary<string, string>>
{
{
"example",
new Dictionary<string, string>
{
{ "i don't understand the builk API (yet)", "some value" }
}
}
});
}
references:
full project
Accessing Dapr secrets building block using Dapr .NET SDK
but I'd like a solution that I can use elsewhere, if possible
In general, we need to use the abstract methods defined in the DarpClient.
Related
I am trying to write a Unit Tests to a legacy code using Mockito.
But I am not able to understand how do I mock it. Can some please help.
The real problem I am facing is actually I am not able to decide how to make a decision on what exactly is to be mocked? Below is the code. I have looked at numerous videos on YouTube and read many Mockito Tutorials but all of them seem to be guiding mostly about how to use the Mockito Framework.
The basic idea of what to Mock is still unclear. Please guide if you have a better source. I do understand that the code showed below does not really showcase the best coding practice.
public class DataFacade {
public boolean checkUserPresent(String userId){
return getSomeDao.checkUserPresent(userId);
}
private SomeDao getSomeDao() {
DataSource dataSource = MyDataSourceFactory.getMySQLDataSource();
SomeDao someDao = new SomeDao(dataSource);
}
}
Well, a Unittest, as the name implies, tests a unit. You should mock anything that isn't part of that unit, especially external dependencies. For example, a DAO is normally a good example for something that will be mocked in tests where the class under tests uses it, because otherwise you would really have actual data access in your test, making it slower and more prone to failure because of external reasons (for example, if your dao connects to a Datasource, that Datasource's target (for example, the database) may be down, failing your test even if the unit you wanted to test is actually perfectly fine). Mocking the DAO allows you to test things independently.
Of course, your code is bad. Why? You are creating everything in your method by calling some static factory method. I suggest instead using dependency injection to inject the DAO into your facade, for example...
public DataFacade(SomeDao someDao) {
this.someDao = someDao;
}
This way, when instantiating your DataFacade, you can give it a dao, which means, in your test you can give it a mock, for example...
#Test
public void testSomething() {
SomeDao someDaoMock = Mockito.mock(SomeDao.class);
DataFacade toTest = new DataFacade(someDaoMock);
...now you can prepare your mock to do something and then call the DataFace method
}
Dependency injection frameworks like Spring, Google Guice, etc. can make this even easier to manage, but the first step is to stop your classes from creating their own dependencies, but let the dependencies be given to them from the outside, which makes the whole thing a lot better.
You should "mock" the inner objects that you use in your methods.
For example if you write unit tests for DataFacade->checkUserPresent, you should mock the getSomeDao field.
You have a lot of ways to do it, but basically you can make getSomeDao to be public field, or get it from the constructor. In your test class, override this field with mocked object.
After you invoke DataFacade->checkUserPresent method, assert that checkUserPresent() is called.
For exmaple if you have this class:
public class StudentsStore
{
private DbReader _db;
public StudentsStore(DbReader db)
{
_db = db;
}
public bool HasStudents()
{
var studentsCount = _db.GetStudentsCount();
if (studentsCount > 0)
return true;
else
return false;
}
}
And in your test method:
var mockedDb = mock(DbReader.class);
when(mockedDb.GetStudentsCount()).thenReturn(1);
var store = new StudentsSture(mockedDb);
assertEquals(true,store.HasStudents());
I need to mock a DbSet with RhinoMock. I found a way to mock IDbSet, but not DbSet. I found a way with another mocking framework, but i have to use RhinoMock. Can somebody please translate it to rhino mock?
I found this on http://www.loganfranken.com/blog/517/mocking-dbset-queries-in-ef6/:
private static DbSet<T> GetQueryableMockDbSet<T>(params T[] sourceList) where T : class
{
var queryable = sourceList.AsQueryable();
var dbSet = new Mock<DbSet<T>>();
dbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider);
dbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);
dbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
dbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator());
return dbSet.Object;
}
Thanks
Update
While RhinoMocks supports mocking multiple interfaces with the same mock, as I utilized in my initial answer, it apparently doesn't support explicit intefaces, which DbSet utilizes for IQueryable. As #Dosihris pointed out in the comment, it throws an exception saying
Due to how CLR handles explicit interface implementation, we're not able to proxy this method.
This appears to be an exception from the version of Castle.DynamicProxy (v2.1.0.5967) embedded in RhinoMocks, which is from pre-2010. Newer versions of DynamicProxy support this, so if you really wanted to be adventurous, you could recompile RhinoMocks with an updated version of DynamicProxy.
Or, you could try referencing DynamicProxy directly in your test project and using binding redirects to force RhinoMocks to use the newer version. Given the age of the version in RhinoMocks, there's likely incompatibilities with the newer DynamicProxy APIs, so this is likely not going to be successful.
Or, you could move to a framework that is still actively maintained, such as Moq or NSubstitute (which both use newer versions of DynamicProxy).
This is the equivalent logic using RhinoMocks:
using Rhino.Mocks;
private static DbSet<T> GetQueryableMockDbSet<T>(params T[] sourceList) where T : class
{
var queryable = sourceList.AsQueryable();
var dbSet = Rhino.Mocks.MockRepository.GenerateMock<DbSet<T>, IQueryable<T>>();
((IQueryable<T>)dbSet).Expect(m => m.Provider).Return(queryable.Provider);
((IQueryable<T>)dbSet).Expect(m => m.Expression).Return(queryable.Expression);
((IQueryable<T>)dbSet).Expect(m => m.ElementType).Return(queryable.ElementType);
((IQueryable<T>)dbSet).Expect(m => m.GetEnumerator())
.Return(null) // will be ignored but still the API requires it
.WhenCalled((methodInvokation) => methodInvokation.ReturnValue = queryable.GetEnumerator());
return dbSet;
}
Depending on whether you want to do verification that the properties were called or not, you may want to use .Stub() instead of .Expect() in each of the above.
So I've build a WebAPI from scratch, including some best practices that I've found online such as Dependency Injection and Domain<->DTO mapping using auto mapper etc.
My API Controllers now look similar to this
public MyController(IMapper mapper)
{
}
and AutoMapper Registry:
public AutoMapperRegistry()
{
var profiles = from t in typeof(AutoMapperRegistry).Assembly.GetTypes()
where typeof(Profile).IsAssignableFrom(t)
select (Profile)Activator.CreateInstance(t);
var config = new MapperConfiguration(cfg =>
{
foreach (var profile in profiles)
{
cfg.AddProfile(profile);
}
});
For<MapperConfiguration>().Use(config);
For<IMapper>().Use(ctx => ctx.GetInstance<MapperConfiguration>().CreateMapper(ctx.GetInstance));
}
I'm also building a few test cases, implementing MOQ, and this is where i feel a little unsure. whenever calling my controllers, I need to pass in an IMapper like this:
var mockMapper = new Mock<IMapper>();
var controller = new MyController(mockMapper.Object);
But then, how do i configure the IMapper to have the correct mappings? It feels redundant to recreate the same logic I've already created before to configure the Mapper. so I am wondering what is the recommended approach to do this?
That's pretty simple: if you mock IMapper and imagine it as a fully abstract concept of mapping data from one object to another, then you have to treat is an abstraction and not imply there's a real automapper behind it.
First you should not register any existing profile at all, you should instead setup IMapper.Map method to return specific object when given another object.
So for each profile used for specific method you have to do a setup, looking approximately like this:
var mockMapper = new Mock<IMapper>();
mockMapper.Setup(x => x.Map<DestinationClass>(It.IsAny<SourceClass>()))
.Returns((SourceClass source) =>
{
// abstract mapping function code here, return instance of DestinationClass
});
In this case, your test knows nothing about actual IMapper implementation - it just uses it methods to get the data you expect from actual IMapper implementation to receive.
This might me another solution
//auto mapper configuration
var mockMapper = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new AutoMapperProfile()); //your automapperprofile
});
var mapper = mockMapper.CreateMapper();
And then call then controller like so
var controller = new YourController(imapper:mapper,..otherobjects..);
This way it will serve the purpose or else if you create mock object for IMapper then it will return what you ask it to return.
Sorry if this comes across as a stupid question im just not sure how to get started writing some unit tests.
I have a solution containing an api and a unit test project. The api has a repository/interface used for data access using ninject.
My question is how is my best way to unit test my api controllers. I have read a little about Moq but not sure if I need to use it as I want to test against my database.
I have read that I need to use a [TestInitialize] attribute
[TestInitialize]
public void MyTestInitialize()
{
var kernel = NinjectWebCommon.CreatePublicKernel();
kernel.Bind<BusinessController>().ToSelf();
}
My problem is my test project cant resolve CreatePublicKernel
Checking the NinjectWebCommon class in the api there is no function called CreatePublicKernel.
What am I missing here?
Ninject (or other DI library) is used only to provide dependencies into your controller's constructor. E.g. if you need BusinessController which requires two repositories, then controller should have constructor which expects these dependencies:
public BusinessController(IUserRepository userRepository,
IOrderRepository orderRepository)
{
_userRepository = userRepository;
_orderRepository = orderRepository;
}
If you want to write unit tests for your controller, you should provide mocked implementations of these repositories. Use Moq or other framework for creating mocks:
var userRepositoryMock = new Mock<IUserRepository>();
var orderRepositoryMock = new Mock<IOrderRepository>();
// setup mocks here
var controller = new BusinessController(userRepositoryMock.Object,
orderRepositoryMock.Object);
If you are writing integration tests for your controller, you should provide real implementations of these repositories, which use some real database.
var userRepository = new NHibernateUserRepository();
var orderRepository = new NHibernateOrderRepository();
// prepare some data in database here
var controller = new BusinessController(userRepository, orderRepository);
You can move controller instantiation into some method which is executed before each test (SetUp or TestInitialize method) in order to remove code duplication from your tests.
UPDATE: You also can use Ninject for integration testing. Just create Ninject module which will be used both by your real application and integration tests:
public class FooModule : NinjectModule
{
public override void Load()
{
Bind<IUserRepository>().To<NHibernateUserRepository>();
Bind<IOrderRepository>().To<NHibernateOrderRepository>();
Bind<BusinessController>().ToSelf();
}
}
Then use this module both to create kernel in NinjectWebCommon.CreateKernel method and kernel in your tests:
var kernel = new StandardKernel(new FooModule());
var controller = kernel.Get<ValuesController>();
I am just getting involved in Moq and unit testing, so forgive me if this seems obvious (a quick search through SO didn't show me anything like this).
I have an interface with the following proposed member:
void AddFeed(Feed feed);
That I would like to write a unit test for this functionality. The test class has a Moq Repository declared as follows:
static IFeedRepository MockFeedsRepository(params Feed[] feeds)
{
var mockFeedsRepository = new Moq.Mock<IFeedRepository>();
mockFeedsRepository.Expect(x => x.Feeds).Returns((feeds.AsQueryable));
return mockFeedsRepository.Object;
}
How should the mock repository declaration be modified to include this new desired behavior or should I create a different Moq (and just how would that be done).
My assumption is that after creating the mock, deriving the unit test will be much easier but hints are greatly appreciated.
Many thanks,
KevDog
I'm also assuming that you would use the AddFeed method like this
Feed myNewFeed = new Feed();
feedRepository.Add(myNewFeed);
and that you're not using it like this (which is poor design)
IFeedRepository feedRepository = new FeedRepository();
Feed myNewFeed = new Feed(feedRepository);
...
myNewFeed.Save();
I'm going to guess that you would want to then have a test something like this:
[Test]
public void TheTest()
{
IFeedRepository repository = MockFeedsRepository({feed1, feed2, feed3});
Feed newFeed = new Feed();
repository.Add(newFeed);
Assert.AreEqual(4,repository.Count());
}
If that's the case then the test isn't actually testing anything other than your implementation of a mock in-memory repository. Is that what you really need to be doing?
I'd suggest that what you want to be doing is testing the L2Sql implementation of the repository instead, or testing how classes interact with the IFeedRepository interface.
And if you want to test the usage of the IFeedRepository interface then just do something simple like
[Test]
public void TheTest()
{
IFeedRepository repository = Moq.Mock<IFeedRepository>();
Feed newFeed = new Feed();
repository.Expect(r => r.Add(newFeed)); //no return as it's a void method
//repository.Expect(r => r.Add(newFeed)).Throws(new ApplicationException()); --Test handing of exceptions
//Code to hit the .Add() method
//Assert the Add method was called.
}
For tips on asserting if a method was called, see Using Moq to determine if a method is called
I hope that helps