How to test a service that only connects other services

I’m currently scratching my and my colleagues head about whether and how we could test SyncService::syncFoo in any meaningful way
that does not involve basically recreating the whole call tree as mocks.

Edit: It is not a microservice its a Service Class within one project – there was some confusion in the answers/comments

We could Mock all three dependencies and make sure the right Message is passed to the Queue but that seems useless as we would reflect the implementation 1:1 in the test.
The example code is a bit stripped down but it represents what we want to achieve very nicely.

Should we use a completely different approach? Is it ok to NOT test the sync service?

// this should be the signature we want to call
SyncService.syncFoo(Entity)

we now want to:

  • Get a list of endpoints our message should be delivered to based on the passed entity
  • create a message based on the passed entity
  • dispatch the message using the queue

Our current basic approach:

Class MsgQueue 
{
  // tested
  public dispatch(msg, endpoints[])
}

Class MsgFactory
{
  // tested
  create(Entity)
}

Class EndpointRepository()
{
  // tested
  getEndpoints(Entity)
}

Class SyncService()
{
    MsgQueue
    MsgFactory
    EndpointRepository

    public sync(Entity) 
    {
        endPoints = this.EndpointRepository.getEndPoints(Entity)

        if endPoints.empty() 
        { 
           return
        }

        msg = this.MsgFactory.create(Entity)
        
        this.MsgQueue.dispatch(msg, endPoints)
    }
}

9

Given that you have very limited logic in this service I think mocking is a reasonable approach.

Essentially the output of the function is the dispatch call, you could break this out to make testing more obvious, or just check that the mock method is called with the correct arguments.

Yes there will be more mock setup than code tested. But that’s just the nature of your code here.

The other approach would be to upgrade to an integration test. I can imagine this might be complex if you are testing that two things are synced. But if you are not confident that a unit test assures that, then an Integration test is the way to go.

1

To reappropriate a quote from Jeff Goldblum in Jurassic Park; you were so busy making everything a service, that you failed to stop and think whether it needed to be a library.

Not everything should be a service. Nothing in this question leads me to believe that you need a separate runtime and app lifecycle.

I have multiple occasions where I want to trigger the three steps described above and I don’t want to duplicate the three steps

The need for reusability does not lead to the need for a service.

The alternative here is to use a library and refer to it during these “multiple occasions” that you talk about.

How you distribute this library is contextual. Maybe you’re working with a monorepo, maybe Nuget makes sense for your scenario, … Whatever fits the bill here.

We could Mock all three dependencies and make sure the right Message is passed to the Queue but that seems useless as we would reflect the implementation 1:1 in the test.

It sounds to me like that is precisely what your library’s purpose is. So if you were to write a test, yeah that’s how I’d go about it.

Maybe you think this is too trivial to test. While I generally raise the bar on what needs to be tested when something has public consumers, there’s still the reasonable cut-off that trivial code does not need to be tested. I’d err towards testing it but the opposite is arguable.

However, if you think it’s that trivial, maybe reconsider if it’s too trivial to warrant a library, let alone a microservice?

1

Is it ok to NOT test the sync service?

TDD, in its early forms, sends mixed messages here. At the time, people thought “never write a line of code without a failing test” was a good way to communicate what they were doing. But even in the original book (Test Driven Development by Example), Beck admitted that this wasn’t an absolute.

The heuristic I normally use:

  • Complicated code must be easy to test
  • Code that is hard to test must be “so simple there are obviously no deficiencies”

Therefore…

Is it ok to NOT test the sync service?

Yes, if it is simple enough.

Note that there is some tension here: you are probably going to end up judging this on whether it is simple enough today, but to some extent you also need practices that let you discover later that you left (some) code untested before the change that means its no longer “simple”.

When you have code that is both complicated and hard to test, refactor to separate the two. For example, if we look at your branching code alone, we might consider

public sync(Entity) 
{
    endPoints = this.EndpointRepository.getEndPoints(Entity)
    theLogic(Entity, endPoints)
}

theLogic(Entity, endPoints) {
    if ! endPoints.empty() {
        doSomethingUseful(Entity, endPoints)
    }
}

doSomethingUseful(Entity, endPoints) {
    msg = this.MsgFactory.create(Entity)
    this.MsgQueue.dispatch(msg, endPoints)
}

In my judgment, both sync and doSomethingUseful would meet the “so simple there are obviously no deficiencies” criteria.

I’d probably pass theLogic untested in a code review, but if you needed to have a test it might make sense to refactor a little further. One way to do that is to change from direct coupling to indirect coupling:

theLogic(Entity, endPoints) {
  theTestableLogic(Entity, endPoints, this.doSomethingUseful)
}

theTestableLogic(Entity, endPoints, theNextStep) {
   if ! endPoints.empty() {
      theNextStep(Entity, endPoints)
   }
}

For a toy problem, the ceremony dominates the useful work – there’s a reason that HelloWorld doesn’t have a lot of tests! But the ceremony grows much more slowly than complexity, so it can make sense to introduce seams when working in “real” code.

Given the answer of Ewan on the ‘how to test’: https://softwareengineering.stackexchange.com/a/446658/433888 I’ll try to reply to the ‘should we test it’ part of the question.

For me it is reasonable to test this class, especially when you start taking into account the unhappy scenario’s.
The intention of the method is to get data of an entity synchronized across different endpoints. The data from the repository and the endpoints could be on another machine.

With that in mind, what should happen in the method/class/system when any following occurs:

  • the repository is not available
  • the queue is not available
  • one or more endpoints are unavailable/returning (validation) errors/..

The tests should allow to simulate several of these scenario’s, and it could be done via mocking. These mocks could be setup to throw an exception in case that they are being called. Then will be about how and where you want to handle the problems and at what point you consider the data as correctly synchronized.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật