I'm new to writing unit tests. I've started writing unit tests for my java classes using Mockito and Junit5. I'm not really sure if what I'm following is the right way to test a class.
Testing approach followed :-
Spy the class under test and check if it is returning the correct response. Example :-
Java Class A :-
Let's assume that this class has a method that performs deserialization using Jackson or Gson library.
Code :-
public Student deserializeResponseBody(String responseBody) {
return GsonUtil.fromJson(responseBody, Student.class);
}
Test Java Class A :-
Spy Class A in this test class. Call the method of Class A and check
if I'm getting the correct response using Assertions library.
Code :-
#Spy
private A a;
#ParameterizedTest
#MethodSource(value = "readResponseFromFile")
Student student = a.deserializeResponseBody(responseBody);
assertNotNull(student, "Deserialized Response is null");
Please let me know if there's a better approach that I can use for writing the tests.
Related
I have a controller class:
#Controller("/x")
class Controller {
#Get
fun index(): String {
return "test test"
}
#Post
fun dopost (userid) = executelogin(login.userId)
}
This controller depends on the executelogin method down below:
fun executelogin(userid) =
do things
If I want to write a unit test, how would I go about using a dependancy injection to introduce a version of the executelogin method. Below is what I have so far and I am not sure if I am doing it correctly:
#MicronautTest
class Controllertest(val method: executelogin()) {
#Inject
lateinit var client: RxHttpClient
#Test
fun testController(){
val request: HttpRequest<String> = HttpRequest.POST("/hello","test")
val body: String = client.toBlocking().retrieve(request)
assertNotNull(body)
assertEquals(method,method)
}
}
Above in the unit test, I am making the executelogin method a paramter for the controllertest class, which I believe is called a method injection. I was wondering if this was the correct way to go about this or if adjustments need to be made. I apologise if some of the code does not quite make sense, I am new to micronaut and the concept of dependancy injections.
If I want to write a unit test, how would I go about using a
dependancy injection to introduce a version of the executelogin
method.
You can't go about using dependency injection to introduce a version fo the executelogin method, at least not directly you can't. Micronaut doesn't support method injection.
This isn't what you asked but just as an FYI... A common thing to do would be to inject some object that contains the method that you want to call.
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 am trying to test an http server functionality and this is the first time I get exposed to the notions of mocks, stubs and fakes. I'm reading this book that it says mocking is describing the state of a complex object at a certain moment, like a snapshot, and testing the object as it is actually the real one. right? I understand this. what I don't understand is what is the point of writing unit tests and assertions of certain cases that we fully describe in the mock object. If we set the expectations of arguments and return values on the mocking object, and we test for those exact values, the test will always pass. Please correct me. I know I am missing something here.
Mocks, Stubs or anything similar serves as a substitute for the actual implementation.
The idea of mocks is basically to test a piece of code in a isolated environment, substituting the dependencies for a fake implementation. For example, in Java, suppose we want to test the PersonService#save method:
class PersonService {
PersonDAO personDAO;
// Set when the person was created and then save to DB
public void save(Person person) {
person.setCreationDate(new Date());
personDAO.save(person);
}
}
A good aproach is creating a unit test like this:
class PersonServiceTest {
// Class under test
PersonService personService;
// Mock
PersonDAO personDAOMock;
// Mocking the dependencies of personService.
// In this case, we mock the PersonDAO. Doing this
// we don't need the DB to test the code.
// We assume that personDAO will give us an expected result
// for each test.
public void setup() {
personService.setPersonDao(personDAOMock)
}
// This test will guarantee that the creationDate is defined
public void saveShouldDefineTheCreationDate() {
// Given a person
Person person = new Person();
person.setCreationDate(null);
// When the save method is called
personService.save(person);
// Then the creation date should be present
assert person.getCreationDate() != null;
}
}
In another words, you should use mock to substitute dependencies of your code to an "actor" that can be configured to return an expected result or assert some behaviours.
I am trying to use Mockito to test my GWTP application.
I am trying to Mock my View,Proxy,Placemanager and eventbus.
I tried using
#Mock
AbcView abc;
and Abcview abc = Mockito.mock(AbcView.class);
However every time the mocked view is instantiated as null.
How shall i address the same?
Once the view is mocked i will be able go on with testing my presenter class, as the constructor of presenter has following code:
getView().setUiHandlers( this );
so until view is instantiated properly null pointer exception is thrown.
Did you run your test using the MockitoJUnitRunner runner?
#RunWith(MockitoJUnitRunner.class)
public class ExampleTest {
#Mock
private List list;
#Test
public void shouldDoSomething() {
list.add(100);
}
}
Besides #Sydney's response, you also need o make sure that AbcView.class is not final. I forget whether a final class results in a null or a runtime error, but that can be a cause for some sort of unexpected behavior -- one way or another, the mocking doesn't work. And if the class is not final, you need to make sure that any methods you stub on that mock are not final.
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