3

Typically in C# I use dependency injection to help with mocking;

public void UserService
{
 public UserService(IUserQuery userQuery, IUserCommunicator userCommunicator, IUserValidator userValidator)
 {
 UserQuery = userQuery;
 UserValidator = userValidator;
 UserCommunicator = userCommunicator;
 }
 ...
 public UserResponseModel UpdateAUserName(int userId, string userName)
 {
 var result = UserValidator.ValidateUserName(userName)
 if(result.Success)
 {
 var user = UserQuery.GetUserById(userId);
 if(user == null)
 {
 throw new ArgumentException();
 user.UserName = userName;
 UserCommunicator.UpdateUser(user);
 }
 }
 ...
 }
 ...
}
public class WhenGettingAUser
{
 public void AndTheUserDoesNotExistThrowAnException()
 {
 var userQuery = Substitute.For<IUserQuery>();
 userQuery.GetUserById(Arg.Any<int>).Returns(null);
 var userService = new UserService(userQuery);
 AssertionExtensions.ShouldThrow<ArgumentException>(() => userService.GetUserById(-121));
 }
}

Now in something like F#: if I don't go down the hybrid path, how would I test workflow situations like above that normally would touch the persistence layer without using Interfaces/Mocks?

I realize that every step above would be tested on its own and would be kept as atomic as possible. Problem is that at some point they all have to be called in line, and I'll want to make sure everything is called correctly.

Robert Harvey
201k55 gold badges470 silver badges682 bronze badges
asked Jun 25, 2012 at 19:31
4
  • 5
    In theory, unit testing in a functional language is a much easier proposition than OOP testing, because functions merely return values (i.e. no side effects) and there's no mutable state. Commented Jun 25, 2012 at 19:35
  • @ElYusubov: Please don't put tags in question titles; see meta.stackexchange.com/questions/128548/… for more information. Commented Jun 25, 2012 at 19:38
  • I repeat: don't put tags in question titles. We already have a tagging system, and it already has the F# tag in it. Commented Jun 25, 2012 at 20:14
  • 1
    Just saw your comment. Will not put tags for further edits, Thanks ! Commented Jun 25, 2012 at 20:16

2 Answers 2

6

Typically, I would go about this by writing a function that returns a representation of the action that I want to perform on the external resource rather than performing the operation itself. This way the logic and the act of IO are decoupled and testing is much easier.

answered Jun 25, 2012 at 20:12
0
2

The same way you do in C#, but instead of passing the mock into the constructor, you pass it to the function itself (or as a part of a parameter passed to the function).

answered Jun 25, 2012 at 20:15

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.