Tag - UnitTesting

Entries feed - Comments feed

2015-05-18

CQRS Persistence Service of any DDD object with mORMot

We introduced DDD concepts some time ago, in a series of articles in this blog. At that time, we proposed a simple way of using mORMot types to implement DDD in your applications. But all Domain Entitities being tied to the framework TSQLRecord class did appear as a limitation, breaking the  […]

Continue reading

2015-05-03

SOLID Design Principles

Single-to-rule-them-all class

I've just updated the documentation part about the SOLID Design Principles.
The former blog article (almost 4 years old!) sounds like a bit deprecated now...
This is why I would extract here an updated version of this material.

Ensure you checked the corresponding part of the mORMot documentation, which is the updated reference, and probably the easiest to read - including links to all the other documentation.

The acronym SOLID is derived from the following OOP principles (quoted from the corresponding Wikipedia article):

  • Single responsibility principle: the notion that an object should have only a single responsibility;
  • Open/closed principle: the notion that "software entities ... should be open for extension, but closed for modification";
  • Liskov substitution principle: the notion that "objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program” - also named as "design by contract";
  • Interface segregation principle: the notion that "many client specific interfaces are better than one general purpose interface.";
  • Dependency inversion principle: the notion that one should "Depend upon Abstractions. Do not depend upon concretions.". Dependency injection is one method of following this principle, which is also called Inversion Of Control (aka IoC).

If you have some programming skills, those principles are general statements you may already found out by yourself. If you start doing serious object-oriented coding, those principles are best-practice guidelines you would gain following.

They certainly help to fight the three main code weaknesses:

  • Rigidity: Hard to change something because every change affects too many other parts of the system;
  • Fragility: When you make a change, unexpected parts of the system break;
  • Immobility: Hard to reuse in another application because it cannot be disentangled from the current application.

Continue reading

2013-02-03

Log to the console

Our framework features an integrated logging class, ready to be enabled for support and statistics.

For debugging purposes, it could be very handy to output the logging content to a console window.
It enables interactive debugging of a Client-Server process, for instance: you can interact with the Client, then look in real time at the server console window, and inspect which requests are processed, without the need to open the log file.

Depending on the events, colors will be used to write the corresponding information. Errors will be displayed as light red, for instance.

Continue reading

2012-10-14

Advanced mocks and stubs

Let's see some advanced topics about mORMot's mocking and stubbing features:

  • How to handle complex values in parameters / arguments or results, like record;
  • Stubbing via a custom delegate or callback;
  • Calls tracing.

Continue reading

Interfaces in practice: dependency injection, stubs and mocks

In order to fulfill the SOLID principles, two features are to be available when handling interfaces:

  • Dependency injection; 
  • Stubbing and mocking of interfaces for proper testing.

We will show now how mORMot provides all needed features for such patterns, testing a simple "forgot my password" scenario: a password shall be computed for a given user name, then transmitted via SMS, and its record shall be updated in the database.

Continue reading

Stubs and Mocks for Delphi with mORMot

Our mORMot framework is now able to stub or mock any Delphi interface.

As usual, the best way to explain what a library does is to look at the code using it.
Here is an example (similar to the one shipped with RhinoMocks) of verifying that when we execute the "forgot my password" scenario, we remembered to call the Save() method properly:

procedure TMyTest.ForgotMyPassword;
var SmsSender: ISmsSender;
    UserRepository: IUserRepository;
begin
  TInterfaceStub.Create(TypeInfo(ISmsSender),SmsSender).
    Returns('Send',[true]);
  TInterfaceMock.Create(TypeInfo(IUserRepository),UserRepository,self).
    ExpectsCount('Save',qoEqualTo,1);
  with TLoginController.Create(UserRepository,SmsSender) do
  try
    ForgotMyPassword('toto');
  finally
    Free;
  end;
end;

And... that's all, since the verification will take place when IUserRepository instance will be release.

If you want to follow the "test spy" pattern (i.e. no expectation defined a priori, but manual check after the execution), you can use:

procedure TMyTest.ForgotMyPassword;
var SmsSender: ISmsSender;
    UserRepository: IUserRepository;
    Spy: TInterfaceMockSpy;
begin
  TInterfaceStub.Create(TypeInfo(ISmsSender),SmsSender).
    Returns('Send',[true]);
  Spy := TInterfaceMockSpy.Create(TypeInfo(IUserRepository),UserRepository,self);
  with TLoginController.Create(UserRepository,SmsSender) do
  try
    ForgotMyPassword('toto');
  finally
    Free;
  end;
  Spy.Verify('Save');
end;

This is something unique with our library: you can decide if you want to use the classic "expect-run-verify" pattern, or the somewhat more direct "run-verify" / "test spy" pattern.
With mORMot, you pick up your mocking class (either TInterfaceMock or TInterfaceMockSpy), then use it as intended. You can even mix the two aspects in the same instance! It is just a matter of taste and opportunity for you to use the right pattern.

Continue reading

2011-08-20

Enhanced Log viewer

We already shipped a sophisticated set of logging classes some month ago.

Since then, its features have been enhanced, and the system has been deeply interfaced with our main ORM framework. Now almost all low-level or high-level operations can be logged on request.

But since the log files tend to be huge (for instance, if you set the logging for our unitary tests, the 6,000,000 unitary tests creates a 280 MB log file), a log viewer was definitively in need.

Continue reading

2010-12-17

Don't weep, take a breath, and maintain

In a message posted in the EMB forum, Anthony wrote that he "inherited this stuff"... Maintaining a Delphi application pays the bills, but... is sometimes frustrating.

Here are some advices or experiment sharing.

Continue reading

2010-07-23

Unit Testing light in Delphi

Automated Unit Testing is a great improvement in coding safe applications.

If you don't know about it, visit http://xprogramming.com/index.php then come back here, and you'll discover how we implement unit testing in a KISS way, in pure Delphi code.

Continue reading