6

I creating Web Api using .Net Core 2.0. I'm using Active Directory Graph API (https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-devquickstarts-graph-dotnet) for performing creating new user. I created IADGraphService with such interface

interface IADGraphService 
{
    bool CreateUser(UserModel model);
    IList<UserModel> GetUsers();
    bool UpdateUser(UserModel model);
    bool DeleteUser(string userObjectId);
}

I'm thinking about creating integration test like:

// arrange
var service = new ADGraphService();

// act
bool result = service.CreateUser(new UserModel(){ Email = "test@example.com", ..... });
var users = service.GetUsers();

// assert
result.Should().Be(true);
users.Should().Contain(user => user.Email == "test@example.com");

Or maybe unit test implementation of such interface:

// arrange
......
var fakeHttpClient = new Mock<IHttpClient>();
fakeHttpClient.Setup(x => x.PostAsync(url, userModelContent)).Returns(mockJsonResult);
var service = new ADGraphService(fakeHttpClient.Object);

// act
var result = service.CreateUser(new UserModel { Email = "test@example.com", .......});

// assert 
result.Should().Be(true);

Which one should be used for such case?

  • If you need integration test why not? It is look good. only that the CreateUser is part of arrange not act – Sergey K Nov 02 '17 at 16:43
  • @Serghei just wondering, is it the best option. I googled a lot of articles and they told that I should mock results of what 3rd party API provides. – Ivan Zaporozhchenko Nov 02 '17 at 16:54
  • if you will Mock 3rd party API such WebService and etc it will be a Unit Test and not Integrations Test in my daily job I use both of them. you can read here about it https://stackoverflow.com/questions/10752/what-is-the-difference-between-integration-and-unit-tests – Sergey K Nov 02 '17 at 17:01
  • I edited question a little bit. I actually have a unit test in mind and I added it to my question. The question is which one is better for such case? Unit or integration test? – Ivan Zaporozhchenko Nov 02 '17 at 17:06
  • The second one Unit Test is better because you want to test behavior of your class ADGraphService I answered below – Sergey K Nov 02 '17 at 17:08
  • But for testing integrations with external service you should write Integration test without mocks – Sergey K Nov 03 '17 at 10:09
  • So, do you propose to use both? – Ivan Zaporozhchenko Nov 03 '17 at 10:18
  • Yes both, but Integration test should be not on your class but only for implementation of HttpClient. because behavior of ADGraphService class you will test in Unit tests with Mocked IHttpClient. – Sergey K Nov 03 '17 at 16:02

2 Answers2

10

A good strategy is to never mock code you don't own. You should have a layer of integration tests that actually call Azure AD and prove that it's doing what you intend.

To elaborate on the strategy:

  • Write a thin wrapper around the third-party code, exposing only the operations your code will actually need. (Looks like you've already done this with your ADGraphService / IADGraphService.)
  • Write integration tests that test your thin wrapper (ADGraphService), and prove that its public operations really do work the way you intend them to.
  • Then when you're testing higher-level objects, you can use mocks for IADGraphService. You've already proven (via your integration tests) that you understand how your wrapper should work, so you can mock sensible behavior.

Sounds to me like you're on exactly the right track with your integration tests. You're writing your own interface, and exposing only the behaviors that your code will need. Your integration tests prove that those methods actually do what you intend - if Microsoft makes a breaking change, your tests will tell you.

Then when you're testing higher-level code (code that uses IADGraphService), you can mock out IADGraphService, because it's code you own and you can safely mock it.

Joe White
  • 94,807
  • 60
  • 220
  • 330
0

If you need to test behavior of your class ADGraphService you should use Unit Test with Mocked HttpClient. For test integration with web service you should write Integration test on HttpClient not on your Class ADGraphService.

Sergey K
  • 4,071
  • 2
  • 23
  • 34