How can I use .NET Core FirebaseAdminSdk for Unit Testing with Moq - unit-testing

I have been working on .NET Core FirebaseAdminSdk. I want to write unit tests for my own services that are using FirebaseApp class.
FirebaseApp is a sealed class and there is not any interface to moq it.
Is there any way to mock FirebaseApp instance?
private readonly Mock<IFirebaseApp> firebaseApp = new Mock<IFirebaseApp>();
I need an interface something like this.

It's generally not a good idea to try to mock sealed classes like FirebaseApp, because they are designed to be used in a specific way and mocking them can lead to unexpected behavior and make it difficult to test your code correctly.
Instead of trying to mock FirebaseApp, you can use a technique called "dependency injection" to make it easier to test your code. Here's how it works:
Create an interface that defines the methods and properties that you need from FirebaseApp. For example:
public interface IFirebaseApp
{
string Name { get; }
FirebaseAppOptions Options { get; }
Task<string> GetAccessTokenAsync(bool forceRefresh);
void Delete();
}
Modify your code to accept an instance of IFirebaseApp through its
constructor or a property, rather than creating a new instance of
FirebaseApp directly. This is called "dependency injection".
In your unit tests, create a mock implementation of IFirebaseApp
using a mocking framework like Moq. Then pass an instance of the
mock to your code when you create an instance of your service.
This will allow you to easily control the behavior of FirebaseApp in your tests, and make it easier to test different scenarios.

Related

How to decide what to mock in Java Unit Tests?

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());

When using Ninject for dependeny injection is it best practices to use Ninject in your unit tests or use a mocking framework

I am using ninject to inject dependencies in my production environment. I see two options when it comes to writing unit tests. I can either create concrete classes and inject them using ninject, Or I can use a mocking framework like just mock.
My thought process is to just use both and have the deciding factor be whether or not the TestInterface can be constructed in a reusable way. This way we dont waste time writing the same Mocked method to return an empty list over and over again.
Is there a best practice for this type of thing?
With unit tests on class, it doesn't make a lot of sense to include the DI container in the "system under test" (SUT).
by principle, a class unit test should test the class and the class only
usually you can't "reuse" the bindings in the unit test, you have to create them unit-test specific. Therefore you're only re-testing ninject, but not how you're applying it. Ninject is already tested. So no real benefit for you.
If you do acceptance testing / unit testing on component or application level, then it makes perfectly sense to include Ninject in the SUT.
For a class-level unit test one usually takes a dynamic proxy based mocking framework like MOQ or FakeItEasy.
given an implementation:
public interface IDependency {
void Foo(string bar);
}
public class SomeClass
{
private readonly IDependency dependency;
public SomeClass(IDependency dependency)
{
this.dependency = dependency;
}
public void SomeMethod(string arg)
{
this.dependency.Foo(arg);
}
}
a test would look like (xUnit flavor):
public class SomeClassTest
{
private readonly Mock<IDependency> dependency;
private SomeClass testee;
public SomeClassTest()
{
this.dependency = new Mock<IDependency>();
this.testee = new SomeClass(this.dependency.Object);
}
[Fact]
public void SomeMethod_MustPassArgumentToFoo()
{
const string expectedArgument = "AnyArgument;
this.testee.SomeMethod(expectedArgument);
this.dependency.Verify(x => x.Foo(expectedArgument));
}
}
JustMock has NInject built into it plus a mocking container based on it.
Injecting mocks of dependencies is done automatically when you fetch the instance for the first time:
var container = new MockingContainer<ClassUnderTest>();
var testee = container.Instance;
Plus, you can use NInject's syntax for fine-grained control of the injection behavior, as well as JustMock's syntax for configuring mock behavior.

How to unit test a class that consumes a web service?

I have a class (lets call it A) that:
In the constructor takes a config and based on it, creates a stub of
a web service and stores a reference to it in a private field.
Has a few methods that call web methods and some stuff inbetween.
I started to create a unit test that:
Creates an instance of a class A with a dummy configuration.
Through reflection it injects the mocked web service stub.
Although that web service has plenty of methods.
Should I mock them all (in every test, with different data)?
Or maybe I should create another layer that encapsulates only the web methods that are being used?
Or there is another approach?
You should create a wrapper interface around your webservice, and make your class under test take a dependency on that interface, rather than directly on the webservice; you can then mock the interface. Only make that interface expose the methods of the webservice that you find interesting. This is known as a facade pattern, and is detailed here.
Without having a clue about what you're testing, aim for something like this:
public interface IWebserviceWrapper
{
Whatever DoStuff(int something);
}
public class WebserviceWrapper : IWebserviceWrapper
{
private WebService _theActualWebservice;
public WebserviceWrapper(Webservice theService)
{
_theActualWebService = theService;
}
public Whatever DoStuff(int something)
{
return _theActualWebservice.DoSomething(something);
}
}
Then your test would look like this (in this case, using MOQ)
public void Test_doing_something()
{
Mock<IWebserviceWrapper> _serviceWrapperMock = new Mock<IWebserviceWrapper>();
_serviceWrapperMock.SetUp(m => m.DoStuff(12345)).Returns(new Whatever());
var classUnderTest = new ClassUnderTest(_serviceWrapperMock.Object);
var result = classUnderTest.Dothings(12345);
Assert.Whatever....
}
Short answer Yes :). Long answer you should use some kind of mocking lib for example: http://code.google.com/p/mockito/ and in your unit test mock the WS stub and pass it to the tested class. That is the way of the force :)
When you unit test a class, you always want to make sure to only test that class and not include its dependencies. To do that, you will have to mock your WS to have it return dummy data when methods are called. Depending on your scenarios, you do not have to mock ALL the methods for each test, I would say only those that are used.
For an example about mocking, you can read this article: http://written-in-codes.blogspot.ca/2011/11/unit-tests-part-deux.html

Unit Testing DbContext

I've researched some information about techniques I could use to unit test a DbContext. I would like to add some in-memory data to the context so that my tests could run against it. I'm using Database-First approach.
The two articles I've found most usefull were this and this.
That approach relies on creating an IContext interface that both MyContext and FakeContext will implement, allowing to Mock the context.
However, I'm trying to avoid using repositories to abstract EF, as pointed by some people, since EF 4.1 already implements repository and unit of work patterns through DbSet and DbContext, and I really would like to preserve all the features implemented by the EF Team without having to maintain them myself with a generic repository, as I already did in other project (and it was kind of painful).
Working with an IContext will lead me to the same path (or won't it?).
I thought about creating a FakeContext that inherits from main MyContext and thus take advantage of the DbContext underneath it to run my tests without hitting the database.
I couldn't find similar implementations, so I'm hoping someone can help me on this.
Am I doing something wrong, or could this lead me to some problems that I'm not anticipating?
Ask yourself a single question: What are you going to test?
You mentioned FakeContext and Mocking the context - why to use both? Those are just different ways to do the same - provide test only implementation of the context.
There is one more bigger problem - faking or mocking context or set has only one result: You are not testing your real code any more.
Simple example:
public interface IContext : IDisposable
{
IDbSet<MyEntity> MyEntities { get; }
}
public class MyEntity
{
public int Id { get; set; }
public string Path { get; set; }
}
public class MyService
{
private bool MyVerySpecialNetMethod(e)
{
return File.Exists(e.Path);
}
public IEnumerable<MyEntity> GetMyEntities()
{
using (IContext context = CreateContext())
{
return context.MyEntities
.Where(e => MyVerySpecialNetMethod(e))
.Select(e)
.ToList();
}
}
}
Now imagine that you have this in your SUT (system under test - in case of unit test it is an unit = usually a method). In the test code you provide FakeContext and FakeSet and it will work - you will have a green test. Now in the production code you will provide a another derived DbContext and DbSet and you will get exception at runtime.
Why? Because by using FakeContext you have also changed LINQ provider and instead of LINQ to Entities you are running LINQ to Objects so calling local .NET methods which cannot be converted to SQL works as well as many other LINQ features which are not available in LINQ to Entities! There are other issues you can find with data modification as well - referential integrity, cascade deletes, etc. That is the reason why I believe that code dealing with context / LINQ to Entities should be covered with integration tests and executed against the real database.
I am developing an open-source library to solve this problem.
http://effort.codeplex.com
A little teaser:
You don't have to add any boilerplate code, just simply call the appropriate API of the library, for example:
var context = Effort.ObjectContextFactory.CreateTransient<MyContext>();
At first this might seem to be magic, but the created ObjectContext object will communicate with an in-memory database and will not talk to the original real database at all. The term "transient" refers to the lifecycle of this database, it only lives during the presence of the created ObjectContext object. Concurrently created ObjectContext objects communicate with dedicated database instances, the data is not shared accross them. This enables to write automated tests easily.
The library provides various features to customize the creation: share data across instances, set initial data of the database, create fake database on different data layers... check out the project site for more info.
As of EF 4.3, you can unit test your code by injecting a fake DefaultConnectionFactory before creating the context.
Entity Framework 4.1 is close to being able to be mocked up in tests but requires a little extra effort. The T4 template provides you with a DbContext derived class that contains DbSet properties. The two things that I think you need to mock are the DbSet objects that these properties return and properites and methods you're using on the DbContext derived class. Both can be achieved by modifying the T4 template.
Brent McKendrick has shown the types of modifications that need to be made in this post, but not the T4 template modifications that can achieve this. Roughly, these are:
Convert the DbSet properties on the DbContext derived class into IDbSet properties.
Add a section that generates an interface for the DbContext derived class containing the IDbSet properties and any other methods (such as SaveChanges) that you'll need to mock.
Implement the new interface in the DbContext derived class.

How to mock ObjectContext or ObjectQuery<T> in Entity Framework?

How to mock ObjectContext or ObjectQuery in Entity Framework?
The basic mocking frameworks can only create mocks for interfaces and for abstract classes (but only for abstract/virtual methods).
As the ObjectContext is neither abstract nor interface, it is not so easy to mock it. However, as the concrete model container is generated as partial class (if you use the designer), you can extract the methods/properties you need from it to an interface. In your code, you may use the interface only, that you can mock afterwards.
With the ObjectQuery it is a little bit more easy, as it has a base interface (e.g. IQueryable) that basically contains all the neccessary operations that you usually need (and required for LINQ). So you should expose IQueryable instead of ObjectQuery in your business logic, and you can create mock for that interface.
Other alternative is to hide all data-access related logic into a separate layer (with minimal logic), test this layer with integration tests, and mock it to be able to unit test the other layers.
There are tools (I know only TypeMock) that use the profiling hooks of .NET to generate the mocks. These tools are not limited to mock interfaces or abstract classes, but with them you can mock basically anything, including non-virtual and static methods. With such a tool you don't need to change your business logic in order to allow mocking.
Although this approach is sometimes useful, you have to be aware that extracting the dependencies to interfaces (IoC) is not only helpful for mocking, but also it reduces the dependencies between your components, that has other benefits too.
Personally I like Rhino.Mocks the best from the freeware tools, but we also use TypeMock as well, which is also a great product (but you have to pay for it).
Why can't we just create the actual context object to be used in our tests? Since we don't want our tests to affect the production database, we can always specify a connection string that points to a test database. Before running each test, construct a new context, add the data you will need in your test, proceed with the unit test, then in the test cleanup section, delete all the records that were created during the test. The only side-affect here would be that the auto-increment IDs would be used up in the test database, but since it's a test database - who cares?
I know that most answers regarding this question propose using DI/IoC designs to create interfaces for data contexts etc. but the reason I am using Entity Framework is exactly to not write any interfaces for my database connections, object models, and simple CRUD transactions. To write mock interfaces for my data objects and to write complex queryable objects to support LINQ, defeats the purpose of relying on highly-tested and reliable Entity Framework.
This pattern for unit testing is not new - Ruby on Rails has been using it for a long time and it's worked out great. Just as .NET provides EF, RoR provides ActiveRecord objects and each unit test creates the objects it needs, proceeds with the tests, and then deletes all the constructed records.
How to specify connection string for test environment? Since all tests are in their own dedicated test project, adding a new App.Config file with a connection string for the test database would suffice.
Just think of how much headache and pain this will save you.
I agree with the others you cannot really Mock ObjectContext. You should use EF DbContext because you can mock the underlying DbSet There are quite a lot of post how to do that. So I won't write how to do it. However if you absolutely must use ObjectContext (for some reason) and you want to Unit test it you can use InMemory database.
First install this Nuget package: Effort (Entity Framework Fake ObjectContext Realization Tool), which uses NMemory as the database. Install Effort.EF6 package:
PM> Install-Package Effort.EF6
using System;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using Effort;
public class DbContextHelper
{
//Fake object you can drop this if you are using your own EF context
private class DbObject
{
public Guid Id { get; set; }
public string Name { get; set; }
}
//Fake EF context you can switch with you own EF context
private class FakeDbContext : DbContext
{
public FakeDbContext(DbConnection connection)
: base(connection, true) { }
public virtual DbSet<DbObject> DbObjects { get; set; }
}
private FakeDbContext _dbContext;
public DbContextHelper()
{
//In memory DB connection
DbConnection effortConnection = DbConnectionFactory.CreatePersistent("TestInstanceName");
_dbContext = new FakeDbContext(effortConnection);
}
//You can expose your context instead of the DbContext base type
public DbContext DbContext => _dbContext;
public ObjectContext ObjectContext => ((IObjectContextAdapter)_dbContext).ObjectContext;
//Method to add Fake object to the fake EF context
public void AddEntityWithState(string value, EntityState entityState)
{
DbContext.Entry(new DbObject() { Id = Guid.NewGuid(), Name = value }).State = entityState;
}
}
Usage:
DbContextHelper _dbContextHelper = new DbContextHelper();
_dbContextHelper.AddEntityWithState("added", System.Data.Entity.EntityState.Added);
_dbContextHelper.AddEntityWithState("added", System.Data.Entity.EntityState.Modified);
var objs = _dbContextHelper.ObjectContext.GetObjectStateEntries(EntityState.Modified | EntityState.Added);
There you are you have your object in memory DB.