2017-06-08 60 views
1

我正在尝试使用xUnit和Moq编写一些测试,而且我似乎无法包装我的头如何测试提供给方法的参数已被更改该方法本身。测试方法的参数已更改

这是我有:

[Fact] 
public void WhenCreateAsyncCalledSomePropertyIsSet() 
{ 
    // Arrange 
    var mockSomeService = new Mock<ISomeService>(); 
    var someObject = new SomeObject(); 

    // Act 
    mockSomeService.Setup(x => x.CreateAsync(someObject)).Callback(() => { 
     someObject.SomeProperty = "SomeValue"; 
    }); 

    // Assert 
    Assert.NotNull(someObject.SomeProperty); 
} 

基本上我试图做的是确保当CreateAsync(someObject)被称为它设置someObject参数的SomeProperty财产。我的测试失败..

UPDATE:

我试图测试方法如下:

public class SomeService : ISomeService 
{ 
    private readonly SomeContext _context; 

    public SomeService(SomeContext context) 
    { 
     _context = context; 
    } 

    public async Task CreateAsync(SomeObject someObject) 
    { 
     someObject.SomeProperty = GenerateRandomString(); 

     _context.SomeObjects.Add(project); 

     await _context.SaveChangesAsync(); 
    } 
} 

我想测试SomeProperty是否设置(如上面)当方法被调用。如果我忘记设置它,我想测试失败。

回答

1

该服务紧密耦合到SomeContext实施问题。除非你打算做内存测试,上下文会导致一些复杂性。

摘要背景。

public interface ISomeContext { 
    ISomeSet<SomeObject> SomeObjects { get; set; } 
    Task<int> SaveChangesAsync(); 
} 

该类将重构,以便它不再依赖于实现问题并允许更大的灵活性。

public class SomeService : ISomeService { 
    private readonly ISomeContext _context; 

    public SomeService(ISomeContext context) { 
     _context = context; 
    } 

    public async Task CreateAsync(SomeObject someObject) { 
     someObject.SomeProperty = GenerateRandomString();  
     _context.SomeObjects.Add(project);  
     await _context.SaveChangesAsync(); 
    } 

    string GenerateRandomString() { 
     //...other code 
    } 
} 

而且测试会模拟测试中该主题的依赖关系的功能,并在进行测试时注入该功能。

public Task WhenCreateAsyncCalledSomePropertyIsSet() { 
    // Arrange 
    var mockSomeContext = new Mock<ISomeContext>(); 
    mockSomeContext 
     .Setup(x => x.SaveChangesAsync()) 
     .ReturnsAsync(1); //Because the method under test is async 

    var sut = new SomeService (mockSomeContext.Object); //Actual service, fake context 
    var someObject = new SomeObject(); //actual object 

    Assert.IsNull(someObject.SomeProperty); //making sure it was null to begin with 

    // Act 
    await sut.CreateAsync(someObject); //call method under test. 
    var actual = someObject.SomeProperty; //get the value 

    // Assert 
    Assert.NotNull(actual); //Assert that it was actually set. 
} 

您的真实上下文将来自抽象/接口或由提供该功能的东西包装。

回顾Moq Quickstart以更好地理解框架。