Jasmine – Angular Test @HostListener – Dispatching keyboard Events

Tags

, , , ,

Listener to test:

@HostListener('keydown.esc') onEsc() {
  this.close();
};

Test:

it('keydown.esc Listener', () => {
  spyOn(component, 'close');

  dispatchKeyboardEvent(testWrapperComponent.elm.nativeElement.children[0], 'keydown', 'Escape');

  expect(component.close).toHaveBeenCalled();
});
function dispatchKeyboardEvent(elm: HTMLElement, eventName: string, keyName: string) {
  let event; 

  try {
    // PhantomJS
    event = document.createEvent('KeyboardEvent');
    event.initEvent(eventName, true, false);
    event.key = keyName;
  } catch(e) {
    // Chrome
    event = new KeyboardEvent(eventName, {'key': keyName});
  }

  elm.dispatchEvent(event);
}

export default dispatchKeyboardEvent;

Important points:

1- event should not be defined in the same line with document.createEvent. let event = document…. causes a strong type checking and we cannot assign a key to event. (Error: TS2450, cannot assign because read-only)

2- PhantomJS and Chrome needs different event objects.

Advertisements

Jasmine – Spy an object which is created in the called method

Tags

, ,

Testcase:

methodToBeTested() {
  const obj = new MyType();
  obj.do();
}

Test:

it('test', () => {
  spyOn(MyType.prototype, 'do');
});

This setup does not let the do method run. In case we cannot spy a function directly through the object, we can spy “the type”.

Jasmine – Test whether a method is called

Tags

, ,

Language: Typescript (Angular Component Test)

Method to be tested:

methodToBeTested(ev) {
  ev.call();
}

Test:

it('test', () => {
   const ev = {call: () => {}};

   // Run Test
   component.methodToBeTested(ev);

   // Controls
   expect(ev.call).toHaveBeenCalled();
});

Error:  <call> : Expected a spy, but got Function.

Solution:

it('test', () => {
   const ev = {call: () => {}};

   spyOn(ev, 'call');

   // Run Test
   component.methodToBeTested(ev);

   // Controls
   expect(ev.call).toHaveBeenCalled();
});

This was easy, since the parameter ev does not have a type.

Method 2:

methodToBeTested(ev: TypeWithMultipleAttributes) {
  ev.call();
}

Test:

it('test', () => {
   const ev = {call: () => {}};
   spyOn(ev, 'call');

   // Run Test
   component.methodToBeTested(ev);

   // Controls
   expect(ev.call).toHaveBeenCalled();
});

Error:  Argument of type {call: () => {}} is not assignable to parameter of type TypeWithMultipleAttributes. Property XXX is missing in type {call: () => {}}.

Reason: we did not create a constant with the correct type. So the content of our test data is very different than the one which we should prepare.

Solution 1:  is to create our test data with the original type:

it('test', () => {
   const ev : TypeWithMultipleAttributes = {X: 1, Y: 'goh', call: () => {}, ...};
   spyOn(ev, 'call');

   // Run Test
   component.methodToBeTested(ev);

   // Controls
   expect(ev.call).toHaveBeenCalled();
});

Solution 2: What if the type has many attributes which we do not want to deal with.. In the end, we will just check if a method is called:

it('test', () => {
   const ev = {call: () => {}};
   spyOn(ev, 'call');

   // Run Test
   component.methodToBeTested(ev as TypeWithMultipleAttributes);

   // Controls
   expect(ev.call).toHaveBeenCalled();
});

as keyword takes our test object (which may have a different content), and passes it through the Typescript’s type validation. This seems like a hack, but cleverly eliminates the need for creating a specified type. Typically the test object should at least contain the attributes, the method in test needs. (In our project, we had a very complex type with more than 10 attributes, but in a specific location we wanted to test just a method call as shown above.)

Jasmine – Spy a service call

Tags

, ,

Language: Typescript (Angular Component Test)

Method to be tested:

methodToBeTested() {
  this.model = this.service.format(this.date);
}

Facts to test:
1- is the format method of service called with the attribute date?
2- is the answer of this method saved to attribute model?

Test:

it('test', done => {
  inject([Service], (service: Service) => {
    comp.date = {year: 2010, month: 5, day: 1};
    const modelValue = 'value';

    spyOn(service, 'format').and.callFake(function (date) {
      // Controls and Spies
      expect(date).toBe(comp.date);
      return modelValue;
    });

    // Start Test
    comp.methodToBeTested();

    // Controls
    expect(comp.model).toBe(modelValue);

    done();
  })();
});

The Power of thenAnswer

Tags

, , ,

Syntax:

when(myMock.method(myObject)).thenAnswer(Answer<?> answer);

or

doAnswer(Answer<?> answer).when(myMock).method(myObject);

 

Use case 1:

You can mock/stub void methods (as i explain in this post) to simulate the behaviour of them, which then will i.e. change the attributes of given arguments:

doAnswer(new Answer<Void>() {
    @Override
    public Void answer(final InvocationOnMock invocation) {
        Object[] args = invocation.getArguments();
        MyObject myObject = (MyObject) args[0];
        myObject.setX(...);
        return null;
    }
}).when(myMock).method(myObject);

 

Use case 2 Background:

You can test your method not just with %100 coverage -which is just the technical part of it-, but also with %100 functional coverage, since you now can stub asynchronous method callbacks. In one of my earlier posts, i have explained how hard it can be to write clever tests. We had our method to be tested:

protected void myMethod(MyObject myObject) {
     myObject.setComment("comment");
     myObjectRepository.update(myObject);
}

At the end we were able to test our whole method like this:

@Mock
private MyObjectDAO myObjectRepositoryMock;
 
@Mock   // we can also use @Spy here, depending on our needs
private MyObject myObjectMock;
 
@Test
public void testMyMethod() {
     // Run Test
     x.myMethod(myObjectMock);
 
     // Control
     InOrder inOrder = inOrder(myObjectMock, myObjectRepositoryMock);
 
     inOrder.verify(myObjectMock).setComment("comment");
     inOrder.verify(myObjectMock, never()).setComment(anyString());
     inOrder.verify(myObjectRepositoryMock).updateMyObject(myObjectMock);
}

.. since the order of the setter & update calls is very critical.

 

Use Case 2:

Today i have realised (thanks to Viet Hung Chu) that the way i test the above method is not that clever. For the above method it works like a charm, but if we had sth like this:

protected void myMethod(MyObject myObject) {
     myObject.setComment("comment");
     myObject.setStar(5);
     myObjectRepository.update(myObject);
}

.. we have problem with our above approach, since by using inOrder we have to define not just the order of each mock interaction, but also the order of each method call; and we do not want that here! We call 2 setters, and our test should run independent of the number of setter calls or the order of those.

     // Control
     InOrder inOrder = inOrder(myObjectMock, myObjectRepositoryMock);
 
     inOrder.verify(myObjectMock).setComment("comment");
     inOrder.verify(myObjectMock, never()).setComment(anyString());
     inOrder.verify(myObjectMock).setStar(5);
     inOrder.verify(myObjectMock, never()).setStar(anyInt());
     inOrder.verify(myObjectRepositoryMock).updateMyObject(myObjectMock);
}
     // Control
     InOrder inOrder = inOrder(myObjectMock, myObjectRepositoryMock);
 
     inOrder.verify(myObjectMock);
     inOrder.verify(myObjectRepositoryMock).updateMyObject(myObjectMock);
}

So we define our method callback with then (an alias of thenAnswer and allows more readable tests):

@Mock
private MyObjectDAO myObjectRepositoryMock;
 
@Test
public void testMyMethod() {
     // Preparation
     MyObject myObject = new MyObject();

     when(myObjectRepositoryMock.updateMyObject(myObject)).then(new Answer<Void>() {
			@Override
			public Void answer(final InvocationOnMock invocation) {
				MyObject myObjectActual = (MyObject) invocation.getArguments()[0];

				// Control
				assertEquals("comment", myObjectActual.getComment());
			    assertEquals(5, myObjectActual.getStar());
				return null;
			}
		});

     // Run Test
     x.myMethod(myObject);
}

Here, in then part, we define the method which will be called when our updateMyObject is called. This way, the order of calls doesn’t matter; all that matters is that at the time of the updateMyObject() call, the correct values are in the correct place.

Advantage 1: We do not have to mock MyObject.
Advantage 2: We do not have to define an order.
Advantage 3: The real test will be performed in that method, at runtime!

 

Use Case 3:

You can set/change the return value of a mock after the mock is defined.

For instance you have a class, for which you need to write 100 test methods, and each of them needs to mock a method, but with slightly different return values. You of course do not want to define that mock in each method separately, but you cannot make sth like this either:

private List<Long> list;

@Before
public void setUp() {
    when(mock.method()).thenReturn(list);
}

@Test
public void testEmptyList() {
    list = new LinkedList<Long>();
    // method call
}

@Test
public void testWithOneElement() {
    list = Arrays.asList(Long.valueOf(125L));
    // method call
}

...

Be aware that we do not just change the object, we also assign to it (different objectIds). So before the each test runs, in setUp our mock behaviour will be defined, and at that exact time of mocking the object list has no value (null). Welcome NullPointerException.

Here comes thenAnswer in play:

private List<Long> list;

@Before
public void setUp() {
    when(mock.method()).thenAnswer(
            new Answer<List<Long>>() {
                @Override
                public List<Long> answer(final InvocationOnMock invocation) {
                    return list;
                }
            });
}

...

Since we now define in setUp, not “return value”, but “the method which will prepare the return value”, and since this method will be called at runtime first, we do not get a nullPointer, and the values we assign in each method will be returned.

Model based software?

Tags

, ,

Summary in one sentence: it’s worth it in the long run.

It is very difficult to give approximate numbers like “If your project should at the end have several 1000 files & has a deadline of let me say less than 1-2 years & if you have less than 50 people, it may not worth it”. Since everything does not just depend on the factors stated above, and since every project has its own unique chemistry, the decision is not easy.

Why?

Everything is about reusability and consistency. As in very basic programming, when you need to use a functionality from different locations, you make a module (class/service/application etc.) from that functionality. The biggest advantages are of course; it eliminates the need to retype it many times and if you eventually need a change, you have to make that modification just in one central location independent of the locations where you use that.

Model based development carries those one step further, so you reuse your modules, not just for the functionality of other modules, but also for different needs like user interface, database, documentation, project planning etc. These are the most basic benefits as stated above respectively:

1- Let you focus more on actual functionality rather than technical details -> Faster -> Cheaper
2- Increased quality by consistency -> Less error-prone + Less tests -> Cheaper

At the beginning it costs of course a lot more, since you probably have to define your own DSL (modelling language), create your own code generator, educate your people etc. But as i also stated at the beginning, in the long run, it’s worth it and you get what you paid for.

How? & Examples

I will try to give you some concrete examples, so that you can at least have a rough idea.

Example: Security
Just the documentation of Spring Security project consists of 155 pages. You can imagine how long it may take to define security concepts for a new page which you want to integrate to your existing application. With model based it may just take one single line and at the end the generator will interpret those lines and create/change the necessary configuration files by generating code:

function ListItem can be seen by Customer, Admin, Manager
attribute itemStockCount can be changed by Manager

* The model is specified on a higher abstraction level than traditional programming languages. So it is easier to understand what is going on, even for those who did not write a single line of code before.

Example: Validation
Imagine the age attribute of a customer, which for our application is not allowed to be smaller than 16. Normally you have to define this constraint in several locations such as database, frontend (html), controller in an MVC environment (@Valid attribute for Spring), backend (repositories), domain object (@Min for bean validation concept of javax package) etc. But if you can generate your database, frontend & backend files, java beans from a single line of model, you may have to define this constraint just in that single location:

attribute age (min=16)

Example: UI
We mostly do have the same design for the same UI elements throughout our application pages. For example a list of items to be displayed for customers on a page, may look like the list which manager use to update the item stock counts on another page. Small differences like pagination, item count per page may also be necessary. So in order not to write the same frontend code (class=..) for the appereance of this list in different locations multiple times -so that we do not have to change multiple files in case of a new design requirement-, we may use our model:

function ListItem {
    list itemList (pagination for Manager, size 20 for Customer)
}

.., so the generated listItem function has an html which displays the content of a list in different ways. And if we want to change how this table look like in terms of color scheme & size & css etc. we make that change in one single location, namely our code-generator.

Another UI example would be that: from the above example of security, the attribute itemStockCount can be changed by Manager. This line of code should / will probably effect not just the security of the application, but also the associated HTML to display the value as read-only for customers.

Spring Examples:

Spring Roo is a Spring project, where code generation is performed with meaningful commands and may give you an idea of how software projects will be developed in the near future.

Just to give you a brief idea; in order to integrate spring security to your roo project, you may just have to write these 2 words in your console, and even a default login page will be created for you.

security setup

You of course can/may have to change application specific configuration in the generated files. But if you want to start a new spring project as quickly as possible where you use spring MVC within security concepts along with the other spring technologies, you may give it a try. After you build your applications’s skeleton, you can always edit the generated files, or give up Spring Roo and continue coding.

Spring Data Jpa is another powerful Spring project which i love. As the name already gives you a clue, it is used to create our repositories. I will write several separate posts about this project later, but as for now, in order to attract your attention :), i leave you alone with this example, so you can see how powerful model-based idea can be:

public interface PersonRepository extends Repository<User, Long> {
     List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
}

That’s it. We can use this interface as our repository, without implementing it! Spring will generate the queries at runtime by interpreting method names. By the way, the standard backend methods like save(), findAll(), count() etc. are already there 🙂  defined in the Spring’s Repository interface and generated at runtime!

Spring RMI Support

Tags

, , ,

What?

RMI (remote method invocation) is the Java version of RPC (remote procedure call). In a client-server architecture, you can have your clients and server in different virtual machines (both must be Java based), but still call your server methods as they were in the same VM.

Local access vs. RMI:
Screen Shot 2015-04-05 at 13.03.21Screen Shot 2015-04-05 at 13.06.08

Why Spring?

Since standard Java remoting protocol (RMI – remote method invocation) has some downsides, Spring people have brought some kind of support -like they always do- to those, who still use this old protocol. Besides the other problems RMI has, like security, latency problems, network failure, which could not be fixed within the RMI, the problem which we -also Sring- focus on here is that RMI violates separation of concerns by coupling business logic to remoting infrastructure. As the service interfaces must extend Remote, and the clients must catch the RemoteExceptions, you can no longer have a POJO. If i have to give one negative side effect of that: you cannot expose a single service over multiple protocols, since you add RMI specific code in it.

Traditional RMI

How?

At server side; define a bean using the RmiServiceExporter to bind your service to RMI registry:

	<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
		<property name="service" ref="itemService"></property>
		<property name="serviceInterface" value="service.ItemService"></property>
		<property name="serviceName" value="itemService"></property>
	</bean>
	<bean id="itemService" class="service.impl.ItemServiceImpl">
		<constructor-arg ref="itemRepository"/>
        ...
	</bean>

I suppose you have already realised that you reference your existing itemService bean within the service attribute. serviceName attribute defines the name which will be called by clients through RMI-URL.

At client side; define the service to be used with a bean type of the RmiProxyFactoryBean, and reference that bean in the same way as you normally reference your own beans. At runtime, spring will create a dynamic proxy of the service exported by the ServiceExporter, and client will communicate with that proxy.

	<bean id="itemService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
		<property name="serviceInterface" value="service.ItemService"></property>
		<property name="serviceUrl" value="rmi://192.168.0.11:1099/itemService"></property>
	</bean>
	<bean id="ClientService" class="...">
		<constructor-arg ref="itemService"/>
        ...
	</bean>

– registryHost and registryPort properties could also have been defined for the serviceExporter bean. Since the server side did not define those explicitly, client uses the default values, localhost and 1099 respectively.

RMI-URL Syntax: rmi://host:port/serviceName

– Service interface must also exist in the application context of the client side, thereby Spring can generate the dynamic proxy.

Spring RMI Architecture

Spring RMI Architecture

Advantages for clients:

1. Spring converts remoteExceptions to a runtime hierarchy, so you do not have to handle those manually.

2. You can easily switch the service through your configuration, without changing your code.

Advantages for server:

1. Since Spring also brings the same approach to other protocols, you can expose a single service over multiple protocols.

2. Transparently expose your services, since service interface does not have to extend Remote.

How to mock void methods?

Tags

, ,

Void methods on mocks do nothing by default. But if we have to spy our objects in order to mock just a part of it, we may also have to mock the void methods. Mocking void methods is a bit tricky since you cannot easily define the result you need.

Our method to be tested:

protected void method(final Map<String, String> fieldMap) {
    ...
}

Since the method does not define a return type, when you try sth like this:

doReturn(xx).when(myMock).method(fieldMap);

you do not get a compilation error, but it does not work either. You get a MockitoException:

‘method’ is a *void method* and it *cannot* be stubbed with a *return value*!
Voids are usually stubbed with Throwables:

Another attempt like this:

when(myMock.method(fieldMap))..

.. causes a compile error, since the above construction with when().. is type-checking of the value that you’re returning, already at compile time, and you see this error:

The method when(T) in the type Mockito is not applicable for the arguments (void)

 

Solution:

Void methods can normally do two different things: throwing an exception or changing the given attribute(s).

1- If we want to simulate the exception case:

doThrow(ourException).when(myMock).method(fieldMap);

 
2- If we want to simulate the behaviour of the method, which changes the given object’s attributes:

		doAnswer(new Answer<Void>() {
			@Override
			public Void answer(final InvocationOnMock invocation) {
				Object[] args = invocation.getArguments();
				@SuppressWarnings("unchecked")
				Map<String, String> fieldMapAsParameter = (Map<String, String>) args[0];
				fieldMapAsParameter.put("key", "value");
				return null;
			}
		}).when(myMock).method(fieldMap);

So our method will be simulated to add a key-value pair to the given fieldMap.

 
3- If we simply want to ignore the method, there is also a doNothing():

doNothing().when(mySpy).method(fieldMap);

As i also wrote above, since the void methods on mocks do nothing by default, this case makes only sense when we use a spy instead of mock.

The higher the pay, the better our performance?

Tags

, ,

“The surprising truth about what motivates us” is a great speech which we watched last week during a training session. This is actually a key concept for those companies who want success:

When to use Mockito Spy?

Tags

, ,

If we only need to mock several methods of a class leaving the rest free to respond to calls normally, we cannot mock it, we have to spy it. Here is an example:

public class MyClass extends MyBaseClass {

	public void myMethod(Product p) {
		p.setDescription("desc");
		save(p);
	}

	public void save(Product p) {
		super.save(p);
	}

If we want to test myMethod, but mock the save method:

	@Spy
	@InjectMocks
	private MyClass myClass;

	@Test
	public void testMyMethod() {
		// Preparation
		Product p = new Product();
		doNothing().when(myClass).save(p);

		// Run Test
		myClass.myMethod(p);

		// Control
		assertEquals("desc", p.getDescription());
		verify(myClass).save(p);
	}

Here if we used @Mock instead of @Spy, we would see this error:

This combination of annotations is not permitted on a single field:
@Mock and @InjectMocks

as we cannot say “I want to mock myClass” and “I also want to test myClass, therefore inject my mocks into it” at the same time.

Code Coverage shows us which lines were executed:

Screen Shot 2015-02-13 at 19.34.44

If our method was not a void one, we would use doReturn() instead of doNothing(), rest remains the same.

        ...
	public Product save(Product p) {
		return super.save(p);
        ...
	@Test
	public void testMyMethod() {
		// Preparation
		Product p = new Product();
		doReturn(null).when(myClass).save(p);
                ...

We could have prepared another product instance with an id, and let the save return that instead of null as hibernate would do; but you get the idea anyway.

Note: As i just wanted to show you how to use @Spy, i intentionally did not evaluate all method results properly, as i would normally do like in this post.

Then my test would look like this:

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {

	@Spy
	@InjectMocks
	private MyClass myClass;

	@Mock
	private Product productMock;

	@Test
	public void testMyMethod() {
		// Preparation
		doNothing().when(myClass).save(productMock);

		// Run Test
		myClass.myMethod(productMock);

		// Control
		InOrder inOrder = Mockito.inOrder(productMock, myClass);

		inOrder.verify(productMock).setDescription("desc");
		verifyNoMoreInteractions(productMock);
		inOrder.verify(myClass).save(productMock);
	}
}

Note 2: I will write a separate post about how to mock super class calls, since it is not readily possible with Mockito.