C# 团结与修女

C# 团结与修女,c#,unit-testing,nunit,moq,unity-container,C#,Unit Testing,Nunit,Moq,Unity Container,我试图对书面方法执行单元测试,但我面临这个问题 这是我的UnityConfig类: public class UnityConfig { #region Unity Container private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => { var container = new UnityContainer();

我试图对书面方法执行单元测试,但我面临这个问题

这是我的UnityConfig类:

public class UnityConfig
{
    #region Unity Container
    private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
    {
        var container = new UnityContainer();
        RegisterTypes(container);
        return container;
    });

    public static IUnityContainer GetConfiguredContainer()
    {
        return container.Value;
    }
    #endregion

    public static void RegisterTypes(IUnityContainer container)
    {
        container.RegisterInstance(AutoMapperConfig.Initialize());
        container.RegisterType<IActiveDirectoryUserService, ActiveDirectoryUserService>();
        container.RegisterType<IUserRepository, InMemoryUserRepository>();
        container.RegisterType<IUserService, UserService>();
    }
}
试验方法:

[Test]
public async Task Test()
{
    var userRepositoryMock = new Mock<IUserRepository>();
    var activeDirectoryUserMock = new Mock<IactiveDirectoryUserService>();
    var mapperMock = new Mock<IMapper>();

    var userService = new UserService(userRepositoryMock.Object, activeDirectoryUserMock.Object, mapperMock.Object);

    await userService.RegisterAsync("name", "user@emial.com", "first name", "last name", "password");

    userRepositoryMock.Verify(x => x.AddAsync(It.IsAny<User>()), Times.Once);
}
你知道为什么在测试过程中不使用这些方法吗?我是否需要向UnityConfig添加一些条目才能使其正常工作

-编辑

private static ISet<User> _users = new HashSet<User>
{
    new User("user1", "ab@rmail.com", "firstnam1", "lastname1", "pass", "salt"),
    new User("user2", "ac@rmail.com", "firstnam2", "lastname2", "pass", "salt"),
    new User("user3", "ad@rmail.com", "firstnam3", "lastname3", "pass", "salt")
};

public async Task<IEnumerable<User>> GetAllAsync()
    => await Task.FromResult(_users);

发生的情况是,模拟不知道如何从异步调用返回,因此当代码试图等待它们时,它失败了。它不一定与您的DI容器有关。在本单元测试中不存在

由于没有提供有关测试中使用的类型的足够信息,因此做出一些假设

给定测试中的方法,让我们假设您有这样的接口

public interface IUserRepository {
    Task<User> GetByNameAsync(string name);
    Task AddAsync(User user);
}
public interface IActiveDirectoryUserService {
    Task<AdUserAccount> GetByNameAsync(string name);
}
public class AdUserAccount {
    public  string Email { get; set; }
    public  string FirstName { get; set; }
    public  string LastName { get; set; }
}

谢谢你的回答。您假定的接口看起来与mint相同。我不明白两件事。对于userRepositoryMock,为什么要调用AddAsync方法?还有adUserMock为什么要创建假帐户?是否有其他库支持异步调用,以便我可以以更温和的方式编写测试?@ironaffee AddAsync返回一个任务。如果您没有设置它,模拟将不会返回任何内容,测试中的方法也不会流到完成状态。对于其他依赖项,情况也是如此。它的设置不正确。在测试中,对依赖项进行模拟,以便测试中的方法可以单独测试,而不会因使用具体实现而产生任何连锁反应。正在测试的方法也是异步的,因此在安排测试时需要考虑到这一点。@Iron窗帘已经解决了这一问题。我这样问是因为从你的问题历史来看,你有一个不接受答案的习惯。最后一次是在2014年。如果这个答案解决了你的问题,考虑把它标记为答案,这样帖子就可以被认为是解决了的。为什么你在ValActudioReTryUsAs= AcAudioActudieCurryUSerServ.GETBynAsAsMyCnCym返回时,为模拟广告调用创建假帐号?
private static ISet<User> _users = new HashSet<User>
{
    new User("user1", "ab@rmail.com", "firstnam1", "lastname1", "pass", "salt"),
    new User("user2", "ac@rmail.com", "firstnam2", "lastname2", "pass", "salt"),
    new User("user3", "ad@rmail.com", "firstnam3", "lastname3", "pass", "salt")
};

public async Task<IEnumerable<User>> GetAllAsync()
    => await Task.FromResult(_users);
public interface IUserRepository {
    Task<User> GetByNameAsync(string name);
    Task AddAsync(User user);
}
public interface IActiveDirectoryUserService {
    Task<AdUserAccount> GetByNameAsync(string name);
}
public class AdUserAccount {
    public  string Email { get; set; }
    public  string FirstName { get; set; }
    public  string LastName { get; set; }
}
[Test]
public async Task Test() {
    //Arrrange
    var name = "name";
    var email = "user@emial.com";
    var firstname = "first name";
    var lastname = "last name";

    var userRepositoryMock = new Mock<IUserRepository>();
    //Testing that it returns no user for that name so return null from async call
    userRepositoryMock.Setup(_ => _.GetByNameAsync(name)).ReturnsAsync((User)null);
    //Need this to make sure async call runs to completion
    userRepositoryMock.Setup(_ => _.AddAsync(It.IsAny<User>())).Returns(Task.FromResult((object)null));

    var activeDirectoryUserMock = new Mock<IActiveDirectoryUserService>();
    //fake account for mock AD call
    var adUser = new AdUserAccount {
        Email = email,
        FirstName = firstname,
        LastName = lastname
    };            
    //Need fake ad account to return from async call
    activeDirectoryUserMock.Setup(_ => _.GetByNameAsync(name)).ReturnsAsync(adUser);

    var mapperMock = new Mock<IMapper>();

    var userService = new UserService(userRepositoryMock.Object, activeDirectoryUserMock.Object, mapperMock.Object);

    //Act
    await userService.RegisterAsync(name, email, firstname, lastname, "password");

    //Assert
    userRepositoryMock.Verify(x => x.AddAsync(It.IsAny<User>()), Times.Once);
}